underworld 1.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.
Files changed (365) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +339 -0
  5. data/Rakefile +48 -0
  6. data/app/assets/fonts/DroidNaskh-Bold.ttf +0 -0
  7. data/app/assets/fonts/DroidNaskh-Regular.ttf +0 -0
  8. data/app/assets/fonts/OpenSans-Bold.ttf +0 -0
  9. data/app/assets/fonts/OpenSans-BoldItalic.ttf +0 -0
  10. data/app/assets/fonts/OpenSans-ExtraBold.ttf +0 -0
  11. data/app/assets/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
  12. data/app/assets/fonts/OpenSans-Italic.ttf +0 -0
  13. data/app/assets/fonts/OpenSans-Light.ttf +0 -0
  14. data/app/assets/fonts/OpenSans-LightItalic.ttf +0 -0
  15. data/app/assets/fonts/OpenSans-Regular.ttf +0 -0
  16. data/app/assets/fonts/OpenSans-Semibold.ttf +0 -0
  17. data/app/assets/fonts/OpenSans-SemiboldItalic.ttf +0 -0
  18. data/app/assets/images/underworld/select2-spinner.gif +0 -0
  19. data/app/assets/images/underworld/select2.png +0 -0
  20. data/app/assets/images/underworld/select2x2.png +0 -0
  21. data/app/assets/javascripts/underworld/application.js +16 -0
  22. data/app/assets/javascripts/underworld/dashboard/application.js.erb +30 -0
  23. data/app/assets/javascripts/underworld/dashboard/functions.js.erb +50 -0
  24. data/app/assets/javascripts/underworld/dashboard/init.js.coffee +33 -0
  25. data/app/assets/javascripts/underworld/dashboard/lib/actions.js +7 -0
  26. data/app/assets/javascripts/underworld/dashboard/lib/amd.js.coffee.erb +0 -0
  27. data/app/assets/javascripts/underworld/dashboard/lib/flash_message.js +71 -0
  28. data/app/assets/javascripts/underworld/dashboard/lib/locale.js +14 -0
  29. data/app/assets/javascripts/underworld/dashboard/lib/misc.js +5 -0
  30. data/app/assets/javascripts/underworld/dashboard/lib/string.js +3 -0
  31. data/app/assets/javascripts/underworld/dashboard/lib/ujs_patches.js.coffee +28 -0
  32. data/app/assets/javascripts/underworld/dashboard/manifest.js +5 -0
  33. data/app/assets/javascripts/underworld/dashboard/variables.js.erb +6 -0
  34. data/app/assets/javascripts/underworld/groups.js +2 -0
  35. data/app/assets/javascripts/underworld/home.js +2 -0
  36. data/app/assets/javascripts/underworld/i18n.js +13 -0
  37. data/app/assets/javascripts/underworld/simple.js +20 -0
  38. data/app/assets/javascripts/underworld/users.js +2 -0
  39. data/app/assets/stylesheets/underworld/dashboard/loadindicator.scss +17 -0
  40. data/app/assets/stylesheets/underworld/dashboard/ltr/application.css +38 -0
  41. data/app/assets/stylesheets/underworld/dashboard/ltr/base.css.scss +0 -0
  42. data/app/assets/stylesheets/underworld/dashboard/rtl/application.css +11 -0
  43. data/app/assets/stylesheets/underworld/dashboard/rtl/base.css.scss +0 -0
  44. data/app/assets/stylesheets/underworld/dashboard/share.scss +62 -0
  45. data/app/assets/stylesheets/underworld/dashboard/variables.scss +9 -0
  46. data/app/assets/stylesheets/underworld/ltr/application.css +0 -0
  47. data/app/assets/stylesheets/underworld/rtl/application.css +0 -0
  48. data/app/assets/stylesheets/underworld/simple/ltr/application.css +2 -0
  49. data/app/assets/stylesheets/underworld/simple/rtl/application.css +2 -0
  50. data/app/assets/stylesheets/underworld/simple/rtl/rtl.scss +16 -0
  51. data/app/assets/stylesheets/underworld/simple/share.scss +11 -0
  52. data/app/controllers/underworld/api_controller.rb +133 -0
  53. data/app/controllers/underworld/application_controller.rb +16 -0
  54. data/app/controllers/underworld/assets_controller.rb +6 -0
  55. data/app/controllers/underworld/dashboard/application_controller.rb +43 -0
  56. data/app/controllers/underworld/dashboard/groups_controller.rb +85 -0
  57. data/app/controllers/underworld/dashboard/profile_controller.rb +49 -0
  58. data/app/controllers/underworld/dashboard/user_messages_controller.rb +27 -0
  59. data/app/controllers/underworld/dashboard/users_controller.rb +116 -0
  60. data/app/controllers/underworld/dashboard_controller.rb +16 -0
  61. data/app/controllers/underworld/omniauth/callbacks_controller.rb +24 -0
  62. data/app/helpers/underworld/application_helper.rb +4 -0
  63. data/app/helpers/underworld/dashboard_helper.rb +107 -0
  64. data/app/helpers/underworld/groups_helper.rb +4 -0
  65. data/app/helpers/underworld/home_helper.rb +4 -0
  66. data/app/helpers/underworld/users_helper.rb +8 -0
  67. data/app/models/application_record.rb +3 -0
  68. data/app/models/underworld/concerns/assignment.rb +16 -0
  69. data/app/models/underworld/concerns/user/auth_definitions.rb +87 -0
  70. data/app/models/underworld/concerns/user/gravatar.rb +11 -0
  71. data/app/models/underworld/concerns/user/mongoid_fields.rb +81 -0
  72. data/app/models/underworld/concerns/user/permission.rb +47 -0
  73. data/app/models/underworld/concerns/user/user_roles.rb +24 -0
  74. data/app/models/underworld/group.rb +57 -0
  75. data/app/models/underworld/permission.rb +43 -0
  76. data/app/models/underworld/user.rb +81 -0
  77. data/app/models/underworld/user_message.rb +6 -0
  78. data/app/policies/underworld/admin_only_policy.rb +66 -0
  79. data/app/policies/underworld/application_policy.rb +55 -0
  80. data/app/policies/underworld/group_policy.rb +8 -0
  81. data/app/policies/underworld/user_message_policy.rb +9 -0
  82. data/app/policies/underworld/user_policy.rb +9 -0
  83. data/app/views/angular/auth/groups/details.html +2 -0
  84. data/app/views/angular/auth/groups/index.html +2 -0
  85. data/app/views/angular/auth/groups/new.html +2 -0
  86. data/app/views/angular/auth/index.html +30 -0
  87. data/app/views/angular/auth/profile/edit.html +54 -0
  88. data/app/views/angular/auth/users/details.html +28 -0
  89. data/app/views/angular/auth/users/index.html +6 -0
  90. data/app/views/angular/auth/users/new.html +57 -0
  91. data/app/views/angular/conversations/details.html +19 -0
  92. data/app/views/angular/conversations/index.html +13 -0
  93. data/app/views/angular/conversations/new.html +39 -0
  94. data/app/views/angular/conversations/show.html +6 -0
  95. data/app/views/angular/conversations/show_details.html +15 -0
  96. data/app/views/angular/fields/boolean/boolean.html +4 -0
  97. data/app/views/angular/fields/control-combo/control-list.html +19 -0
  98. data/app/views/angular/fields/datetime/datetime.html +10 -0
  99. data/app/views/angular/fields/datetime/time.html +25 -0
  100. data/app/views/angular/fields/file/file.html.slim +0 -0
  101. data/app/views/angular/fields/float/float.html +4 -0
  102. data/app/views/angular/fields/image/image.html +1 -0
  103. data/app/views/angular/fields/integer/integer.html +4 -0
  104. data/app/views/angular/fields/relation/relation.html +44 -0
  105. data/app/views/angular/fields/string/string.html +22 -0
  106. data/app/views/angular/fields/tag/tag.html +1 -0
  107. data/app/views/angular/fields/text/text.html +4 -0
  108. data/app/views/angular/filter/index.html +15 -0
  109. data/app/views/angular/index.html +3 -0
  110. data/app/views/angular/locale/fa.po +25 -0
  111. data/app/views/angular/locale/templates.pot +24 -0
  112. data/app/views/angular/logs/index.html +6 -0
  113. data/app/views/angular/modules.html +0 -0
  114. data/app/views/angular/nav.html.erb +39 -0
  115. data/app/views/angular/underworld/views/generic_add_view.html.slim +5 -0
  116. data/app/views/devise/registrations/edit.html.erb +29 -0
  117. data/app/views/devise/registrations/new.html.erb +38 -0
  118. data/app/views/devise/sessions/new.html.erb +37 -0
  119. data/app/views/devise/shared/_links.erb +19 -0
  120. data/app/views/devise/shared/_omni_link.erb +33 -0
  121. data/app/views/kaminari/_first_page.html.slim +3 -0
  122. data/app/views/kaminari/_gap.html.slim +2 -0
  123. data/app/views/kaminari/_last_page.html.slim +3 -0
  124. data/app/views/kaminari/_next_page.html.slim +3 -0
  125. data/app/views/kaminari/_page.html.slim +3 -0
  126. data/app/views/kaminari/_paginator.html.slim +13 -0
  127. data/app/views/kaminari/_prev_page.html.slim +3 -0
  128. data/app/views/layouts/underworld/application.html.erb +79 -0
  129. data/app/views/layouts/underworld/dashboard.html.erb +52 -0
  130. data/app/views/layouts/underworld/simple.html.erb +27 -0
  131. data/app/views/underworld/api/v1/conversations/create.json.jbuilder +1 -0
  132. data/app/views/underworld/api/v1/conversations/destroy.json.jbuilder +1 -0
  133. data/app/views/underworld/api/v1/conversations/index.json.jbuilder +1 -0
  134. data/app/views/underworld/api/v1/conversations/reply.json.jbuilder +1 -0
  135. data/app/views/underworld/api/v1/conversations/show.json.jbuilder +14 -0
  136. data/app/views/underworld/api/v1/conversations/trash.json.jbuilder +1 -0
  137. data/app/views/underworld/api/v1/groups/create.json.jbuilder +4 -0
  138. data/app/views/underworld/api/v1/groups/destroy.html.erb +2 -0
  139. data/app/views/underworld/api/v1/groups/destroy.json.jbuilder +1 -0
  140. data/app/views/underworld/api/v1/groups/edit.html.erb +2 -0
  141. data/app/views/underworld/api/v1/groups/index.html.erb +2 -0
  142. data/app/views/underworld/api/v1/groups/index.json.jbuilder +6 -0
  143. data/app/views/underworld/api/v1/groups/new.html.erb +2 -0
  144. data/app/views/underworld/api/v1/groups/show.html.erb +2 -0
  145. data/app/views/underworld/api/v1/groups/show.json.jbuilder +5 -0
  146. data/app/views/underworld/api/v1/groups/update.json.jbuilder +4 -0
  147. data/app/views/underworld/api/v1/logs/index.json.jbuilder +1 -0
  148. data/app/views/underworld/api/v1/permissions/index.json.jbuilder +1 -0
  149. data/app/views/underworld/api/v1/permissions/user_permissions.json.jbuilder +1 -0
  150. data/app/views/underworld/api/v1/users/create.html.erb +2 -0
  151. data/app/views/underworld/api/v1/users/create.json.jbuilder +1 -0
  152. data/app/views/underworld/api/v1/users/destroy.json.jbuilder +1 -0
  153. data/app/views/underworld/api/v1/users/distroy.html.erb +2 -0
  154. data/app/views/underworld/api/v1/users/edit.html.erb +2 -0
  155. data/app/views/underworld/api/v1/users/index.html.erb +2 -0
  156. data/app/views/underworld/api/v1/users/index.json.jbuilder +4 -0
  157. data/app/views/underworld/api/v1/users/show.html.erb +2 -0
  158. data/app/views/underworld/api/v1/users/show.json.jbuilder +2 -0
  159. data/app/views/underworld/api/v1/users/update.json.jbuilder +1 -0
  160. data/app/views/underworld/dashboard/groups/_form.html.slim +68 -0
  161. data/app/views/underworld/dashboard/groups/create.js.erb +3 -0
  162. data/app/views/underworld/dashboard/groups/edit.html.slim +3 -0
  163. data/app/views/underworld/dashboard/groups/errors.js.erb +3 -0
  164. data/app/views/underworld/dashboard/groups/index.html.slim +47 -0
  165. data/app/views/underworld/dashboard/groups/new.html.slim +2 -0
  166. data/app/views/underworld/dashboard/groups/update.js.erb +3 -0
  167. data/app/views/underworld/dashboard/index.html.erb +0 -0
  168. data/app/views/underworld/dashboard/login_required_page.html.erb +5 -0
  169. data/app/views/underworld/dashboard/not_found.html.slim +9 -0
  170. data/app/views/underworld/dashboard/not_found.js.erb +1 -0
  171. data/app/views/underworld/dashboard/profile/_form.html.erb +33 -0
  172. data/app/views/underworld/dashboard/profile/_profile_form.html.erb +33 -0
  173. data/app/views/underworld/dashboard/profile/create.js.erb +3 -0
  174. data/app/views/underworld/dashboard/profile/edit.html.erb +2 -0
  175. data/app/views/underworld/dashboard/profile/edit_password.html.erb +2 -0
  176. data/app/views/underworld/dashboard/profile/errors.js.erb +3 -0
  177. data/app/views/underworld/dashboard/resource/_form.html.slim +33 -0
  178. data/app/views/underworld/dashboard/resource/_input.html.slim +3 -0
  179. data/app/views/underworld/dashboard/resource/create.js.erb +3 -0
  180. data/app/views/underworld/dashboard/resource/destroy.js.erb +2 -0
  181. data/app/views/underworld/dashboard/resource/edit.html.slim +3 -0
  182. data/app/views/underworld/dashboard/resource/index.html.slim +60 -0
  183. data/app/views/underworld/dashboard/resource/new.html.slim +2 -0
  184. data/app/views/underworld/dashboard/resource/show.html.slim +22 -0
  185. data/app/views/underworld/dashboard/resource/update.js.erb +3 -0
  186. data/app/views/underworld/dashboard/shared/_content_header.html.slim +15 -0
  187. data/app/views/underworld/dashboard/shared/_control_sidebar.html.slim +50 -0
  188. data/app/views/underworld/dashboard/shared/_footer.html.slim +7 -0
  189. data/app/views/underworld/dashboard/shared/_header.html.erb +98 -0
  190. data/app/views/underworld/dashboard/shared/_sidebar.html.erb +69 -0
  191. data/app/views/underworld/dashboard/shared/_toolbar.html.slim +0 -0
  192. data/app/views/underworld/dashboard/shared/errors.js.erb +3 -0
  193. data/app/views/underworld/dashboard/user_messages/_form.html.slim +0 -0
  194. data/app/views/underworld/dashboard/user_messages/create.js.erb +0 -0
  195. data/app/views/underworld/dashboard/user_messages/destroy.js.erb +0 -0
  196. data/app/views/underworld/dashboard/user_messages/new.html.slim +72 -0
  197. data/app/views/underworld/dashboard/users/_form.html.slim +73 -0
  198. data/app/views/underworld/dashboard/users/_password_form.html.slim +37 -0
  199. data/app/views/underworld/dashboard/users/create.js.erb +3 -0
  200. data/app/views/underworld/dashboard/users/destroy.js.erb +2 -0
  201. data/app/views/underworld/dashboard/users/edit.html.slim +3 -0
  202. data/app/views/underworld/dashboard/users/edit_password.html.slim +1 -0
  203. data/app/views/underworld/dashboard/users/errors.js.erb +3 -0
  204. data/app/views/underworld/dashboard/users/index.html.slim +66 -0
  205. data/app/views/underworld/dashboard/users/new.html.slim +2 -0
  206. data/app/views/underworld/dashboard/users/show.html.slim +6 -0
  207. data/app/views/underworld/dashboard/users/update.js.erb +3 -0
  208. data/app/views/underworld/dashboard/users/update_password.js.erb +3 -0
  209. data/app/views/underworld/relations/_belongs_to.json.jbuilder +11 -0
  210. data/config/initializers/devise.rb +24 -0
  211. data/config/locales/devise.en.yml +59 -0
  212. data/config/locales/devise.fa.yml +58 -0
  213. data/config/locales/underworld.en.yml +96 -0
  214. data/config/locales/underworld.fa.yml +108 -0
  215. data/config/routes.rb +43 -0
  216. data/config/spring.rb +1 -0
  217. data/db/migrate/20131013091000_devise_create_underworld_users.rb +65 -0
  218. data/db/migrate/20131020124701_create_underworld_groups.rb +15 -0
  219. data/db/migrate/20131021170923_create_underworld_permissions.rb +15 -0
  220. data/db/migrate/20131123120422_add_permissions_groups_table.rb +16 -0
  221. data/db/migrate/20140613120923_add_users_groups_table.rb +13 -0
  222. data/db/migrate/20151122115129_add_uniqueness_index_to_users_groups.rb +11 -0
  223. data/db/migrate/20160310105736_create_underworld_user_messages.rb +25 -0
  224. data/db/seeds.rb +49 -0
  225. data/lib/generators/underworld/install_generator.rb +108 -0
  226. data/lib/generators/underworld/resource_generator.rb +70 -0
  227. data/lib/generators/underworld/resources_generator.rb +20 -0
  228. data/lib/generators/underworld/templates/README +21 -0
  229. data/lib/generators/underworld/templates/SPECS +13 -0
  230. data/lib/generators/underworld/templates/api/controller.rb.erb +60 -0
  231. data/lib/generators/underworld/templates/api_controller.rb +2 -0
  232. data/lib/generators/underworld/templates/dashboard/controller.rb.erb +2 -0
  233. data/lib/generators/underworld/templates/dashboard_controller.rb +18 -0
  234. data/lib/generators/underworld/templates/devise.rb +251 -0
  235. data/lib/generators/underworld/templates/features/api.feature +92 -0
  236. data/lib/generators/underworld/templates/features/api.step.rb +7 -0
  237. data/lib/generators/underworld/templates/features/step_definitions/email_steps.rb +206 -0
  238. data/lib/generators/underworld/templates/features/support/email_spec.rb +1 -0
  239. data/lib/generators/underworld/templates/features/support/env.rb +79 -0
  240. data/lib/generators/underworld/templates/javascripts/application.js +19 -0
  241. data/lib/generators/underworld/templates/policy/application_policy.rb +2 -0
  242. data/lib/generators/underworld/templates/policy/policy.rb.erb +2 -0
  243. data/lib/generators/underworld/templates/seeds.rb +1 -0
  244. data/lib/generators/underworld/templates/spec/factories/groups.rb +5 -0
  245. data/lib/generators/underworld/templates/spec/factories/users.rb +10 -0
  246. data/lib/generators/underworld/templates/spec/spec_helper.rb +69 -0
  247. data/lib/generators/underworld/templates/spec/support/devise.rb +3 -0
  248. data/lib/generators/underworld/templates/stylesheets/dashboard/ltr/application.css +3 -0
  249. data/lib/generators/underworld/templates/stylesheets/dashboard/rtl/application.css +3 -0
  250. data/lib/generators/underworld/templates/stylesheets/ltr/application.css +3 -0
  251. data/lib/generators/underworld/templates/stylesheets/rtl/application.css +3 -0
  252. data/lib/generators/underworld/templates/underworld.rb +12 -0
  253. data/lib/generators/underworld/templates/views/create.json.jbuilder.erb +3 -0
  254. data/lib/generators/underworld/templates/views/destroy.json.jbuilder.erb +1 -0
  255. data/lib/generators/underworld/templates/views/index.json.jbuilder.erb +13 -0
  256. data/lib/generators/underworld/templates/views/show.json.jbuilder.erb +6 -0
  257. data/lib/generators/underworld/templates/views/update.json.jbuilder.erb +6 -0
  258. data/lib/generators/underworld/views_generator.rb +57 -0
  259. data/lib/tasks/docs.rake +6 -0
  260. data/lib/tasks/sync.rake +9 -0
  261. data/lib/tasks/underworld_tasks.rake +38 -0
  262. data/lib/underworld.rb +35 -0
  263. data/lib/underworld/action_dispatch.rb +3 -0
  264. data/lib/underworld/api.rb +42 -0
  265. data/lib/underworld/api/groups_api.rb +41 -0
  266. data/lib/underworld/api/permissions_api.rb +24 -0
  267. data/lib/underworld/api/root.rb +15 -0
  268. data/lib/underworld/api/users_api.rb +20 -0
  269. data/lib/underworld/concerns.rb +7 -0
  270. data/lib/underworld/concerns/authorizable.rb +81 -0
  271. data/lib/underworld/configuration.rb +97 -0
  272. data/lib/underworld/dashboard.rb +11 -0
  273. data/lib/underworld/dashboard/dsl.rb +41 -0
  274. data/lib/underworld/dashboard/dsl/base.rb +133 -0
  275. data/lib/underworld/dashboard/dsl/create.rb +116 -0
  276. data/lib/underworld/dashboard/dsl/form_fields_properties.rb +62 -0
  277. data/lib/underworld/dashboard/dsl/index.rb +45 -0
  278. data/lib/underworld/dashboard/dsl/show.rb +6 -0
  279. data/lib/underworld/dashboard/dsl/update.rb +6 -0
  280. data/lib/underworld/dashboard/helpers/box_helpers.rb +129 -0
  281. data/lib/underworld/dashboard/models.rb +2 -0
  282. data/lib/underworld/dashboard/models/sidebar.rb +139 -0
  283. data/lib/underworld/dashboard/sections.rb +2 -0
  284. data/lib/underworld/dashboard/sections/resource.rb +229 -0
  285. data/lib/underworld/dashboard/sections/resource_create.rb +263 -0
  286. data/lib/underworld/dashboard/sections/resource_destroy.rb +27 -0
  287. data/lib/underworld/dashboard/sections/resource_show.rb +96 -0
  288. data/lib/underworld/dashboard/sections/resources_index.rb +113 -0
  289. data/lib/underworld/dashboard/sections/sidebar.rb +41 -0
  290. data/lib/underworld/discovery.rb +8 -0
  291. data/lib/underworld/discovery/permissions.rb +49 -0
  292. data/lib/underworld/engine.rb +53 -0
  293. data/lib/underworld/exceptions.rb +7 -0
  294. data/lib/underworld/extension.rb +18 -0
  295. data/lib/underworld/extension/base.rb +29 -0
  296. data/lib/underworld/fake_assets.rb +5 -0
  297. data/lib/underworld/i18n.rb +101 -0
  298. data/lib/underworld/initialize.rb +0 -0
  299. data/lib/underworld/liquid.rb +7 -0
  300. data/lib/underworld/liquid/block.rb +14 -0
  301. data/lib/underworld/liquid/render_tag.rb +50 -0
  302. data/lib/underworld/liquid/tag.rb +51 -0
  303. data/lib/underworld/middlewares.rb +1 -0
  304. data/lib/underworld/middlewares/locale.rb +29 -0
  305. data/lib/underworld/omniauth.rb +8 -0
  306. data/lib/underworld/omniauth/callbacks.rb +39 -0
  307. data/lib/underworld/orm.rb +30 -0
  308. data/lib/underworld/routes.rb +117 -0
  309. data/lib/underworld/version.rb +3 -0
  310. data/test/controllers/underworld/dashboard/resource_test.rb +118 -0
  311. data/test/dummy/README.rdoc +28 -0
  312. data/test/dummy/Rakefile +6 -0
  313. data/test/dummy/app/assets/javascripts/application.js +13 -0
  314. data/test/dummy/app/assets/javascripts/dashboard/application.js +19 -0
  315. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  316. data/test/dummy/app/assets/stylesheets/dashboard/ltr/application.css +3 -0
  317. data/test/dummy/app/assets/stylesheets/dashboard/rtl/application.css +3 -0
  318. data/test/dummy/app/assets/stylesheets/ltr/application.css +3 -0
  319. data/test/dummy/app/assets/stylesheets/rtl/application.css +3 -0
  320. data/test/dummy/app/controllers/api_controller.rb +2 -0
  321. data/test/dummy/app/controllers/application_controller.rb +6 -0
  322. data/test/dummy/app/controllers/dashboard/application_controller.rb +18 -0
  323. data/test/dummy/app/helpers/application_helper.rb +2 -0
  324. data/test/dummy/app/policies/application_policy.rb +2 -0
  325. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  326. data/test/dummy/bin/bundle +3 -0
  327. data/test/dummy/bin/rails +4 -0
  328. data/test/dummy/bin/rake +4 -0
  329. data/test/dummy/config.ru +4 -0
  330. data/test/dummy/config/application.rb +23 -0
  331. data/test/dummy/config/boot.rb +5 -0
  332. data/test/dummy/config/database.yml +25 -0
  333. data/test/dummy/config/environment.rb +5 -0
  334. data/test/dummy/config/environments/development.rb +29 -0
  335. data/test/dummy/config/environments/production.rb +80 -0
  336. data/test/dummy/config/environments/test.rb +38 -0
  337. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  338. data/test/dummy/config/initializers/devise.rb +251 -0
  339. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  340. data/test/dummy/config/initializers/formstatic.rb +76 -0
  341. data/test/dummy/config/initializers/formtastic.rb +110 -0
  342. data/test/dummy/config/initializers/inflections.rb +16 -0
  343. data/test/dummy/config/initializers/kaminari_config.rb +10 -0
  344. data/test/dummy/config/initializers/mime_types.rb +5 -0
  345. data/test/dummy/config/initializers/secret_token.rb +12 -0
  346. data/test/dummy/config/initializers/session_store.rb +3 -0
  347. data/test/dummy/config/initializers/underworld.rb +11 -0
  348. data/test/dummy/config/initializers/underworld_assets.rb +1 -0
  349. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  350. data/test/dummy/config/locales/en.yml +23 -0
  351. data/test/dummy/config/routes.rb +13 -0
  352. data/test/dummy/lib/templates/slim/scaffold/_form.html.slim +8 -0
  353. data/test/dummy/public/404.html +58 -0
  354. data/test/dummy/public/422.html +58 -0
  355. data/test/dummy/public/500.html +57 -0
  356. data/test/dummy/public/favicon.ico +0 -0
  357. data/test/fabricators/underworld/groups.rb +27 -0
  358. data/test/fabricators/underworld/permissions.rb +14 -0
  359. data/test/fabricators/underworld/users.rb +17 -0
  360. data/test/generators/install_generator_test.rb +84 -0
  361. data/test/integration/underworld/authentication_test.rb +36 -0
  362. data/test/integration/underworld/dashboard_test.rb +64 -0
  363. data/test/test_helper.rb +72 -0
  364. metadata +1045 -0
  365. metadata.gz.sig +0 -0
@@ -0,0 +1,16 @@
1
+ require_dependency 'underworld/dashboard/application_controller'
2
+
3
+
4
+ module Underworld
5
+ class DashboardController < ::Dashboard::ApplicationController
6
+
7
+ before_action :authenticate_user!, :only => [:modules, :index]
8
+
9
+ def index
10
+ redirect_to dashboard_path if params.include? :signin
11
+ end
12
+
13
+ def not_found
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ module Underworld
2
+ module Omniauth
3
+ class CallbacksController < Devise::OmniauthCallbacksController
4
+
5
+ # Create a method for each service you want to override
6
+ # If you do not provide a method a default one will used
7
+ # Here is facebook method for an example
8
+ def facebook
9
+ create_or_find_user
10
+
11
+ if @user.persisted?
12
+ sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
13
+ set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
14
+ else
15
+ session["devise.facebook_data"] = request.env["omniauth.auth"]
16
+ redirect_to new_user_registration_url
17
+ end
18
+ end
19
+
20
+ include Underworld::Omniauth::Callbacks
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,4 @@
1
+ module Underworld
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,107 @@
1
+ require_dependency 'underworld/dashboard/helpers/box_helpers'
2
+
3
+ module Underworld
4
+ module DashboardHelper
5
+ include Underworld::Dashboard::Helpers::BoxHelpers
6
+ include ::ActionView::Helpers::TranslationHelper
7
+ def form_label(resource, name)
8
+ key = "forms.#{@resource.class.name.underscore.to_s.gsub('/', '.')}.#{name}"
9
+ t(key)
10
+ end
11
+
12
+ def localized_time(time)
13
+ # Fixme: Setup and use Rails l10n
14
+ time.strftime("%Y-%m-%d %H:%M")
15
+ end
16
+
17
+ def link_button(title, **options)
18
+ classes = "btn pull-right btn-sm #{options.fetch(:classes, '')}"
19
+ icon_class = options[:icon_class]
20
+ href = options.fetch(:href, '#')
21
+ remote = options.fetch(:remote, false).to_s
22
+
23
+ button = "<a class='#{classes}' href='#{href}' data-remote='#{remote}'>"
24
+
25
+ if icon_class
26
+ button += "<i class='fa fa-#{icon_class}'></i>"
27
+ end
28
+
29
+ button += "<span>#{title}</span>" + '</a>'
30
+
31
+ button.html_safe
32
+ end
33
+
34
+ def action_buttons(buttons)
35
+ buttons_html = ''
36
+
37
+ buttons.each do |button|
38
+ href = button.fetch(:href, '#')
39
+ klass = button.fetch(:class, 'btn-success')
40
+ remote = button.fetch(:remote, false).to_s
41
+ icons = button.fetch(:icon_class, "")
42
+ label = button.fetch(:name, '')
43
+ model = button.fetch(:model, nil)
44
+ action = button.fetch(:policy, nil)
45
+
46
+ with_policy(model, action) do
47
+ buttons_html += "<a class='action-button btn pull-right " +
48
+ "#{klass}' href='#{href}' data-remote='#{remote}'"+
49
+ "data-disable-with='#{spinner} #{label}'>\n" +
50
+ "<i class='fa fa-#{icons}'></i>" +
51
+ label +
52
+ '</a>'
53
+ end
54
+ end
55
+ buttons_html.html_safe
56
+ end
57
+
58
+ # Translate route name to url dynamically
59
+ def get_url(route_name, id = nil, engine = Rails.application)
60
+ return route_name.call if id.nil?
61
+ return route_name.call(id) unless id.nil?
62
+ end
63
+
64
+ def draw_menu(menu)
65
+ klass = menu.class || ''
66
+ klass += 'treeview' if sidebar.children?
67
+ href = menu.url || '#'
68
+
69
+ result = "<li class='#{klass}'> \
70
+ <a href='#{href}'> \
71
+ <i class='#{menu.icon}'></i>
72
+ <span>#{menu.title}</span>
73
+ <span class='label label-primary pull-right'>4</span>
74
+ </a>"
75
+
76
+ if sidebar.respond_to? :children
77
+ result += "<ul class='treeview-menu slide'>"
78
+ sidebar.children.each do |submenu|
79
+ result += "<li>\
80
+ <a href='#{submenu.url}'>
81
+ <i class='#{submenu.icon}'></i>
82
+ #{submenu.title}
83
+ </a>"
84
+ result += draw_menu submenu
85
+ result += '</li>'
86
+ end
87
+ result += '</ul>'
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def spinner
94
+ h "<i class='fa fa-cog fa-lg fa-spin'></i>"
95
+ end
96
+
97
+ def with_policy(model, action, &block)
98
+ if model && action
99
+ if policy(model).send("#{action}?")
100
+ block.call
101
+ end
102
+ else
103
+ block.call
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,4 @@
1
+ module Underworld
2
+ module GroupsHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Underworld
2
+ module HomeHelper
3
+ end
4
+ end
@@ -0,0 +1,8 @@
1
+ module Underworld
2
+ module UsersHelper
3
+ def underworldify_url(url)
4
+ dashboard = Underworld::Engine.dashboard_namespace
5
+ return url.gsub("/#{dashboard}/", "/#{dashboard}#/")
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -0,0 +1,16 @@
1
+ module Underworld
2
+ module Concerns
3
+ # This **concern** provide the default query loading scope for model.
4
+ # Using this, you can make queries like key=value in http request
5
+ # and Model.assignment(key: value) on you model.
6
+ module Assignment
7
+
8
+ def self.included(base)
9
+ base.scope :assignment_query, ->(field, value) do
10
+ base.where(field => value)
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,87 @@
1
+ module Underworld
2
+ module Concerns::User::AuthDefinitions
3
+
4
+ def self.included(base)
5
+
6
+ base.class_eval do
7
+ # Include default devise modules. Others available are:
8
+ # :token_authenticatable, :confirmable,
9
+ # :lockable, :timeoutable and :omniauthable
10
+ @@devise_options = ::Underworld::Engine.devise_options
11
+
12
+ if Devise.omniauth_configs.any?
13
+ devise :omniauthable, :omniauth_providers => Devise.omniauth_configs.keys
14
+ end
15
+ end
16
+ base.extend ClassMethods
17
+ end
18
+
19
+ def name
20
+ if first_name or last_name
21
+ "#{first_name} #{last_name}"
22
+ else
23
+ email
24
+ end
25
+
26
+ end
27
+
28
+ def full_name
29
+ name
30
+ end
31
+
32
+ def admin?
33
+ # TODO: Find a better way to 'admin?'
34
+ groups.where(role: 'admin').exists?
35
+ end
36
+
37
+ # Confirmation not required when using omniauth
38
+ def confirmation_required?
39
+ super && identities.empty?
40
+ end
41
+
42
+ def update_with_password(params, *options)
43
+ if encrypted_password.blank?
44
+ update_attributes(params, *options)
45
+ else
46
+ super
47
+ end
48
+ end
49
+
50
+ # Omniauth users does not need password
51
+ def password_required?
52
+ # TODO: nil? is not suitable for here we should use empty? or blink?
53
+ if Devise.omniauth_configs.any?
54
+ return (provider.nil? || password.nil?) && super
55
+ else
56
+ password.nil? && super
57
+ end
58
+ end
59
+
60
+ module ClassMethods
61
+ def find_from_oauth(auth, signed_in_resource = nil)
62
+ user = User.where(:provider => auth.provider, :uid => auth.uid).first
63
+
64
+ first_name = auth.info.first_name
65
+ last_name = auth.info.last_name
66
+
67
+ if first_name.blank?
68
+ # With first_name being blank last_name is probably is blank too
69
+ name = auth.info.name.split(' ')
70
+ first_name = name[0]
71
+ last_name = name[1,] || ''
72
+ end
73
+ unless user
74
+ user = User.create(first_name: first_name,
75
+ last_name: last_name,
76
+ provider: auth.provider,
77
+ uid: auth.uid,
78
+ email: auth.info.email,
79
+ password: Devise.friendly_token[0,20])
80
+ end
81
+ user
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,11 @@
1
+ module Underworld
2
+ module Concerns::User::Gravatar
3
+ def gravatar
4
+ require 'digest/md5'
5
+ hash = Digest::MD5.hexdigest(email.downcase)
6
+
7
+ # compile URL which can be used in <img src="RIGHT_HERE"...
8
+ "http://www.gravatar.com/avatar/#{hash}"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,81 @@
1
+ module Underworld
2
+ # This module contains all the **Mongoid** related definitions
3
+ module Concerns::User::MongoidFields
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+
8
+ field :first_name, type: String, default: ''
9
+ field :last_name, type: String, default: ''
10
+ field :email, type: String, default: ''
11
+ field :encrypted_password, type: String, default: ''
12
+
13
+ ## Recoverable
14
+ field :reset_password_token, type: String
15
+ field :reset_password_sent_at, type: Time
16
+
17
+ ## Recoverable
18
+ field :remember_created_at, type: Time
19
+
20
+ ## Trackable
21
+ field :sign_in_count, type: Integer, default: 0
22
+ field :current_sign_in_at, type: Time
23
+ field :last_sign_in_at, type: Time
24
+ field :current_sign_in_ip, type: String
25
+ field :last_sign_in_ip, type: String
26
+
27
+
28
+ ## Confirmable
29
+ # field :confirmation_token, type: String
30
+ # field :confirmed_at, type: Time
31
+ # field :confirmation_sent_at, type: Time
32
+ # field :unconfirmed_email, type: String # Only if using reconfirmable
33
+
34
+ # Lockable
35
+ field :failed_attempts, type: Integer, default: 0 # Only if lock strategy is :failed_attempts
36
+ field :unlock_token, type: String # Only if unlock strategy is :email or :both
37
+ field :locked_at, type: Time
38
+
39
+ # Token authenticatable
40
+ field :authentication_token, type: String
41
+
42
+ # run 'rake db:mongoid:create_indexes' to create indexes
43
+ if not Devise.omniauth_providers.empty?
44
+ # Service
45
+ field :provider, type: String, default: ''
46
+ field :uid, type: String
47
+ end
48
+
49
+ if Rails.env.production?
50
+ # Confirmable
51
+ field :confirmation_token, type: String
52
+ field :confirmed_at, type: Time
53
+ field :confirmation_sent_at, type: Time
54
+
55
+ # Only if using reconfirmable
56
+ field :unconfirmed_email, type: String
57
+ end
58
+
59
+
60
+ index({ email: 1 },
61
+ { unique: true, background: true })
62
+ index({ reset_password_token: 1 },
63
+ { unique: true, background: true })
64
+ index({ unlock_token: 1 },
65
+ { unique: true, background: true })
66
+ index({ authentication_token: 1 },
67
+ { unique: true, background: true })
68
+
69
+ # To fix the issue with new mongo
70
+ #def self.serialize_from_session(key, salt)
71
+ # record = to_adapter.get(key[0]["$oid"])
72
+ # record if record && record.authenticatable_salt == salt
73
+ #end
74
+
75
+ if Rails.env.production?
76
+ index({ confirmation_token: 1 },
77
+ { unique: true, background: true })
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,47 @@
1
+ module Underworld
2
+ # This concern contains all the permission related methods
3
+ # to use within `Underworld::User`
4
+ module Concerns::User::Permission
5
+ extend ActiveSupport::Concern
6
+
7
+ def member_of?(group)
8
+ @group_ids ||= self.groups.all.map(&:id)
9
+ @group_ids.include? group.id
10
+ end
11
+
12
+ def has_permission? action, obj
13
+ perm = self.groups.includes(:permissions)
14
+ .where(underworld_permissions: { model: obj, permission_type: action })
15
+ .count
16
+ perm == 1
17
+ end
18
+
19
+ def can_not? action, obj
20
+ !has_permission? action, obj
21
+ end
22
+
23
+ alias_method :can?, :has_permission?
24
+
25
+ def has_ownership?(record)
26
+ has_permission? :ownership, record.name
27
+ end
28
+
29
+ def owned?(record)
30
+ if has_permission? :ownership, record.name
31
+ if record.respond_to? :user
32
+ return true if record.user == self
33
+ return false
34
+ end
35
+
36
+ if record.respond_to? :__owned_by
37
+ return true if record.__owned_by == self
38
+ end
39
+ end
40
+ false
41
+ end
42
+
43
+ def permissions
44
+ groups.includes(:permissions).map(&:permissions).flatten.uniq
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,24 @@
1
+ module Underworld
2
+ # This concern contains all the role related methods
3
+ # to use within `Underworld::User`
4
+ module Concerns
5
+ module User
6
+ module UserRoles
7
+
8
+ # Return an array of user roles.
9
+ def roles
10
+ self.groups.to_a.map(&:role)
11
+ end
12
+
13
+ def role? role
14
+ roles.include? role.to_s
15
+ end
16
+
17
+ # A shortcut for `role? :admin`
18
+ def admin?
19
+ role? :admin
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end