j1_template 2019.4.4 → 2019.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (225) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/themes/j1/layouts/content_generator_app.html +8 -10
  3. data/_includes/themes/j1/layouts/content_generator_blog_archive.html +24 -18
  4. data/_includes/themes/j1/layouts/content_generator_collection.html +10 -12
  5. data/_includes/themes/j1/layouts/content_generator_page.html +11 -14
  6. data/_includes/themes/j1/layouts/content_generator_post.html +10 -12
  7. data/_includes/themes/j1/layouts/content_generator_raw.html +8 -10
  8. data/_includes/themes/j1/layouts/layout_metadata_generator.html +9 -10
  9. data/_includes/themes/j1/layouts/layout_module_generator.html +10 -11
  10. data/_includes/themes/j1/layouts/layout_resource_generator.html +10 -11
  11. data/_includes/themes/j1/layouts/layout_shim_generator.html +14 -20
  12. data/_includes/themes/j1/layouts/layout_theme_generator.html +45 -52
  13. data/_includes/themes/j1/modules/connectors/ad/google-adsense.html +1 -1
  14. data/_includes/themes/j1/modules/connectors/ads +2 -2
  15. data/_includes/themes/j1/modules/connectors/analytic/google-analytics.html +1 -1
  16. data/_includes/themes/j1/modules/connectors/analytics +2 -2
  17. data/_includes/themes/j1/modules/connectors/comment/disqus.html +1 -1
  18. data/_includes/themes/j1/modules/connectors/comments +2 -2
  19. data/_includes/themes/j1/modules/footers/footer_light_generator.html +33 -18
  20. data/_includes/themes/j1/modules/headers/master_header_generator.html +23 -11
  21. data/_includes/themes/j1/modules/navigator/generator.html +3 -3
  22. data/_includes/themes/j1/modules/navigator/generator.olde.html +3 -3
  23. data/_includes/themes/j1/procedures/global/get_category_item.proc +4 -4
  24. data/_includes/themes/j1/procedures/global/pager.proc +12 -5
  25. data/_includes/themes/j1/procedures/global/setup.proc +9 -9
  26. data/_includes/themes/j1/procedures/layouts/content_writer.proc +9 -10
  27. data/_includes/themes/j1/procedures/layouts/default_writer.proc +9 -11
  28. data/_includes/themes/j1/procedures/layouts/module_writer.proc +11 -13
  29. data/_includes/themes/j1/procedures/layouts/resource_writer.proc +8 -10
  30. data/_includes/themes/j1/procedures/posts/collate_calendar.proc +1 -1
  31. data/_includes/themes/j1/procedures/posts/collate_list.proc +1 -1
  32. data/_includes/themes/j1/procedures/posts/collate_timeline.proc +1 -1
  33. data/_layouts/default.html +3 -3
  34. data/_layouts/home.html +2 -2
  35. data/lib/j1/version.rb +1 -1
  36. data/lib/j1_app/j1_auth_manager/_unused/auth_manager.org.2.rb +1086 -0
  37. data/lib/j1_app/j1_auth_manager/_unused/auth_manager.org.rb +1548 -0
  38. data/lib/j1_app/j1_auth_manager/auth_manager.rb +302 -453
  39. data/lib/j1_app/j1_auth_manager/config.rb +13 -0
  40. data/lib/j1_app/j1_auth_manager/helpers.rb +14 -0
  41. data/lib/j1_app/j1_auth_manager/views/auth_manager_ui.erb +99 -87
  42. data/lib/starter_web/Gemfile +1 -1
  43. data/lib/starter_web/_cc_test_data/_config.yml +1 -1
  44. data/lib/starter_web/_cc_test_data/_data/j1_categories.yml +1 -1
  45. data/lib/starter_web/_cc_test_data/_data/j1_polyfills.yml +1 -1
  46. data/lib/starter_web/_cc_test_data/_data/modules/back2top.yml +0 -6
  47. data/lib/starter_web/_cc_test_data/_data/modules/cookiebar.yml +1 -1
  48. data/lib/starter_web/_cc_test_data/_data/modules/defaults/back2top.yml +19 -6
  49. data/lib/starter_web/_cc_test_data/_data/modules/defaults/cookie_consent.yml +8 -0
  50. data/lib/starter_web/_cc_test_data/_data/modules/defaults/cookiebar.yml +8 -0
  51. data/lib/starter_web/_cc_test_data/_data/modules/defaults/jekyll_search.yml +8 -0
  52. data/lib/starter_web/_cc_test_data/_data/modules/defaults/navigator.yml +8 -0
  53. data/lib/starter_web/_cc_test_data/_data/modules/defaults/webhook.yml +23 -15
  54. data/lib/starter_web/_cc_test_data/_data/modules/jekyll_search.yml +8 -8
  55. data/lib/starter_web/_cc_test_data/_data/modules/webhook.yml +26 -19
  56. data/lib/starter_web/_cc_test_data/_data/resources.yml +1 -1
  57. data/lib/starter_web/_config.yml +1 -1
  58. data/lib/starter_web/_data/_defaults/categories.yml +32 -0
  59. data/lib/starter_web/_data/{j1_colors.yml → _defaults/colors.yml} +0 -0
  60. data/lib/starter_web/_data/{j1_font_sizes.yml → _defaults/font_sizes.yml} +0 -0
  61. data/lib/starter_web/_data/{j1_i18n.yml → _defaults/i18n.yml} +0 -0
  62. data/lib/starter_web/_data/{apps → _defaults}/j1_light_gallery.yml +0 -0
  63. data/lib/starter_web/_data/{j1_polyfills.yml → _defaults/polyfills.yml} +1 -1
  64. data/lib/starter_web/_data/{j1_resources.yml → _defaults/resources.yml} +203 -65
  65. data/lib/starter_web/_data/_defaults/template_settings.yml +256 -0
  66. data/lib/starter_web/_data/{j1_categories.yml → _old_configs/j1_categories.yml} +1 -1
  67. data/lib/starter_web/_data/_old_configs/j1_colors.yml +608 -0
  68. data/lib/starter_web/_data/_old_configs/j1_config.yml +256 -0
  69. data/lib/starter_web/_data/_old_configs/j1_font_sizes.yml +26 -0
  70. data/lib/starter_web/_data/_old_configs/j1_i18n.yml +19 -0
  71. data/lib/starter_web/_data/_old_configs/j1_resources.yml +877 -0
  72. data/lib/starter_web/_data/apps/{j1_bootstrap_gallery.yml → _unused/j1_bootstrap_gallery.yml} +0 -0
  73. data/lib/starter_web/_data/apps/{j1_carousel.yml → _unused/j1_carousel.yml} +0 -0
  74. data/lib/starter_web/_data/apps/{j1_justified_gallery.yml → _unused/j1_justified_gallery.yml} +0 -0
  75. data/lib/starter_web/_data/apps/{j1_lightbox.yml → _unused/j1_lightbox.yml} +0 -0
  76. data/lib/starter_web/_data/apps/{j1_link_checker.yml → _unused/j1_link_checker.yml} +0 -0
  77. data/lib/starter_web/_data/apps/_unused/light_gallery.yml +108 -0
  78. data/lib/starter_web/_data/apps/bootstrap_gallery.yml +187 -0
  79. data/lib/starter_web/_data/apps/carousel.yml +511 -0
  80. data/lib/starter_web/_data/apps/defaults/bootstrap_gallery.yml +187 -0
  81. data/lib/starter_web/_data/apps/defaults/carousel.yml +223 -0
  82. data/lib/starter_web/_data/apps/defaults/justified_gallery.yml +245 -0
  83. data/lib/starter_web/_data/apps/defaults/light_gallery.yml +115 -0
  84. data/lib/starter_web/_data/apps/defaults/lightbox.yml +181 -0
  85. data/lib/starter_web/_data/apps/defaults/link_checker.yml +32 -0
  86. data/lib/starter_web/_data/apps/justified_gallery.yml +245 -0
  87. data/lib/starter_web/_data/apps/light_gallery.yml +114 -0
  88. data/lib/starter_web/_data/apps/lightbox.yml +181 -0
  89. data/lib/starter_web/_data/apps/link_checker.yml +32 -0
  90. data/lib/starter_web/_data/blocks/footer.yml +2 -2
  91. data/lib/starter_web/_data/categories.yml +32 -0
  92. data/lib/starter_web/_data/colors.yml +608 -0
  93. data/lib/starter_web/_data/font_sizes.yml +26 -0
  94. data/lib/starter_web/_data/i18n.yml +19 -0
  95. data/lib/starter_web/_data/j1_config.yml +9 -20
  96. data/lib/starter_web/_data/layouts/default.yml +10 -10
  97. data/lib/starter_web/_data/modules/_old_configs/_j1_navigator.yml +2 -2
  98. data/lib/starter_web/_data/modules/{j1_header.yml → _old_configs/j1_header.yml} +0 -0
  99. data/lib/starter_web/_data/modules/{j1_iframe_resizer.yml → _old_configs/j1_iframe_resizer.yml} +0 -0
  100. data/lib/starter_web/_data/modules/{j1_log4javascript.yml → _old_configs/j1_log4javascript.yml} +1 -1
  101. data/lib/starter_web/_data/modules/back2top.yml +7 -14
  102. data/lib/starter_web/_data/modules/cookiebar.yml +1 -1
  103. data/lib/starter_web/_data/modules/defaults/back2top.yml +27 -14
  104. data/lib/starter_web/_data/modules/defaults/cookie_consent.yml +8 -0
  105. data/lib/starter_web/_data/modules/defaults/cookiebar.yml +8 -0
  106. data/lib/starter_web/_data/modules/defaults/framer.yml +272 -0
  107. data/lib/starter_web/_data/modules/defaults/header.yml +221 -0
  108. data/lib/starter_web/_data/modules/defaults/jekyll_search.yml +17 -0
  109. data/lib/starter_web/_data/modules/defaults/log4javascript.yml +120 -0
  110. data/lib/starter_web/_data/modules/defaults/navigator.yml +8 -3
  111. data/lib/starter_web/_data/modules/defaults/webhook.yml +40 -24
  112. data/lib/starter_web/_data/modules/framer.yml +272 -0
  113. data/lib/starter_web/_data/modules/header.yml +221 -0
  114. data/lib/starter_web/_data/modules/j1_navigator_menu.yml +26 -9
  115. data/lib/starter_web/_data/modules/j1_parallax.yml +4 -0
  116. data/lib/starter_web/_data/modules/j1_smooth_scroll.yml +4 -0
  117. data/lib/starter_web/_data/modules/j1_stickybits.yml +4 -0
  118. data/lib/starter_web/_data/modules/j1_theme_switcher.yml +7 -0
  119. data/lib/starter_web/_data/modules/j1_toccer.yml +3 -0
  120. data/lib/starter_web/_data/modules/jekyll_search.yml +27 -3
  121. data/lib/starter_web/_data/modules/log4javascript.yml +120 -0
  122. data/lib/starter_web/_data/modules/navigator.yml +13 -15
  123. data/lib/starter_web/_data/modules/webhook.yml +32 -22
  124. data/lib/starter_web/_data/polyfills.yml +50 -0
  125. data/lib/starter_web/_data/resources.yml +876 -0
  126. data/lib/starter_web/_data/template_settings.yml +279 -0
  127. data/lib/starter_web/apps/protected/netlify-admin/config/_old_configs/config.backup.yml +1 -1
  128. data/lib/starter_web/apps/protected/netlify-admin/config/_old_configs/config.org.yml +1 -1
  129. data/lib/starter_web/apps/protected/netlify-admin/config/_snippets/01_site_configuration/110_resource_settings.yml +1 -1
  130. data/lib/starter_web/apps/protected/netlify-admin/config/_snippets/03_module_configuration/130_module_settings.j1_back2top.yml +24 -15
  131. data/lib/starter_web/apps/protected/netlify-admin/config/_snippets/_examples/config.arrays.yml +1 -1
  132. data/lib/starter_web/apps/protected/netlify-admin/config/config.yml +9 -4
  133. data/lib/starter_web/assets/data/{menu.old.html → _temp/menu.old.html} +0 -0
  134. data/lib/starter_web/assets/data/carousel.json +19 -4
  135. data/lib/starter_web/assets/data/colors.json +12 -11
  136. data/lib/starter_web/assets/data/font_sizes.json +12 -11
  137. data/lib/starter_web/assets/data/galleries.json +19 -2
  138. data/lib/starter_web/assets/data/messages.yml +130 -0
  139. data/lib/starter_web/assets/data/panel.html +32 -9
  140. data/lib/starter_web/assets/data/quicklinks.html +30 -28
  141. data/lib/starter_web/assets/data/themes.json +11 -11
  142. data/lib/starter_web/assets/data/{web_hook.html → webhook.html} +4 -4
  143. data/lib/starter_web/assets/images/master_header/whats-up-1920x1200.png +0 -0
  144. data/lib/starter_web/assets/images/pages/pen/jquery/jQuery-logo.png +0 -0
  145. data/lib/starter_web/assets/images/pages/pen/jquery/jquery-banner-1280x600.jpg +0 -0
  146. data/lib/starter_web/assets/images/pages/pen/jquery/jquery-banner-1920x800.jpg +0 -0
  147. data/lib/starter_web/assets/images/pages/pen/jquery/src/JQuery-Logo.svg +122 -0
  148. data/lib/starter_web/assets/images/pages/pen/jquery/src/banner.psd +0 -0
  149. data/lib/starter_web/assets/images/pages/roundtrip/package.json +1 -1
  150. data/lib/starter_web/assets/themes/j1/{core/js/adapter/back2top.js → adapter/js/_unused/back2top.org.js} +0 -0
  151. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js}/_unused/cookie_consent.button_events.not_moved.js +2 -2
  152. data/lib/starter_web/assets/themes/j1/{core/js/adapter/cookie_consent.js → adapter/js/_unused/cookie_consent.org.js} +2 -2
  153. data/lib/starter_web/assets/themes/j1/{core/js/adapter/master_header.js → adapter/js/_unused/masterheader.org.js} +96 -105
  154. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js/_unused}/navigator.new.kapott.1.js +13 -13
  155. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js/_unused}/navigator.new.kapott.2.js +16 -16
  156. data/lib/starter_web/assets/themes/j1/adapter/js/_unused/octokit.new.js +83 -0
  157. data/lib/starter_web/assets/themes/j1/{core/js/adapter/webhook.js → adapter/js/_unused/octokit.old.js} +72 -64
  158. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js/_unused}/promise_test.js +0 -0
  159. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js}/_unused/template.new-1.js +30 -30
  160. data/lib/starter_web/assets/themes/j1/{core/js/adapter/template.js → adapter/js/_unused/template.new.js} +479 -305
  161. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js/_unused}/template.old.js +31 -31
  162. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js}/_unused/template.org.js +30 -30
  163. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js}/_unused/webhook.eventhandler.not_deferred.js +1 -1
  164. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js}/_unused/webhook.new.js +1 -1
  165. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js}/algolia.js +116 -44
  166. data/lib/starter_web/assets/themes/j1/adapter/js/back2top.js +223 -0
  167. data/lib/starter_web/assets/themes/j1/{core/js/adapter/bs_gallery.js → adapter/js/bootstrap_gallery.js} +138 -67
  168. data/lib/starter_web/assets/themes/j1/{extensions/carousel/js/j1_adapter_carousel.js → adapter/js/carousel.js} +126 -48
  169. data/lib/starter_web/assets/themes/j1/adapter/js/cookie_bar.js +166 -0
  170. data/lib/starter_web/assets/themes/j1/adapter/js/cookie_consent.js +235 -0
  171. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js}/custom.js +90 -39
  172. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js}/example.js +94 -36
  173. data/lib/starter_web/assets/themes/j1/adapter/js/framer.js +199 -0
  174. data/lib/starter_web/assets/themes/j1/adapter/js/justified_gallery.js +339 -0
  175. data/lib/starter_web/assets/themes/j1/adapter/js/lightbox.js +177 -0
  176. data/lib/starter_web/assets/themes/j1/adapter/js/logger.js +237 -0
  177. data/lib/starter_web/assets/themes/j1/adapter/js/master_header.js +548 -0
  178. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js}/navigator.js +152 -123
  179. data/lib/starter_web/assets/themes/j1/adapter/js/octokit.js +440 -0
  180. data/lib/starter_web/assets/themes/j1/adapter/js/scroller.js +173 -0
  181. data/lib/starter_web/assets/themes/j1/adapter/js/searcher.js +197 -0
  182. data/lib/starter_web/assets/themes/j1/adapter/js/stickybits.js +162 -0
  183. data/lib/starter_web/assets/themes/j1/adapter/js/switcher.js +186 -0
  184. data/lib/starter_web/assets/themes/j1/adapter/js/template.js +1368 -0
  185. data/lib/starter_web/assets/themes/j1/{core/js/adapter → adapter/js}/toccer.js +128 -61
  186. data/lib/starter_web/assets/themes/j1/core/js/template.js +13 -13
  187. data/lib/starter_web/assets/themes/j1/core/js/template.js.map +1 -1
  188. data/lib/starter_web/assets/themes/j1/core/js/template.min.js +1 -1
  189. data/lib/starter_web/assets/themes/j1/extensions/cookiebar/js/cookiebar.js +25 -10
  190. data/lib/starter_web/assets/themes/j1/extensions/cookiebar/js/cookiebar.min.js +20 -0
  191. data/lib/starter_web/assets/themes/j1/extensions/light_gallery/js/lg-fullscreen.js +62 -72
  192. data/lib/starter_web/assets/themes/j1/extensions/light_gallery/js/lg-fullscreen.min.js +2 -2
  193. data/lib/starter_web/collections/posts/private/series/_posts/2018-11-01-docker-using-shared-folders.adoc +1 -1
  194. data/lib/starter_web/collections/posts/public/featured/_posts/2018-06-01-top-open-source-static-site-generators.adoc +1 -0
  195. data/lib/starter_web/collections/posts/public/featured/_posts/2018-07-01-what-is-a-static-site.adoc +1 -1
  196. data/lib/starter_web/collections/posts/public/featured/_posts/2019-04-22-about-cookies.adoc +1 -0
  197. data/lib/starter_web/collections/posts/public/jekyll/_posts/2018-05-01-confusion-about-base-url.adoc +1 -0
  198. data/lib/starter_web/package.json +15 -9
  199. data/lib/starter_web/pages/private/bookshelf/{100_about_jekyll_collections.adoc → 100_whats_up.adoc} +4 -4
  200. data/lib/starter_web/pages/private/bookshelf/200_book_shelf_biography.adoc +1 -1
  201. data/lib/starter_web/pages/private/bookshelf/300_book_shelf_fantasy.adoc +1 -1
  202. data/lib/starter_web/pages/private/bookshelf/400_book_shelf_romance.adoc +1 -1
  203. data/lib/starter_web/pages/private/pen/jquery/deferred_try_catch.adoc +118 -0
  204. data/lib/starter_web/pages/public/blog/navigator/archive.html +12 -4
  205. data/lib/starter_web/pages/public/blog/navigator/archive/categoryview.html +11 -3
  206. data/lib/starter_web/pages/public/blog/navigator/archive/dateview.html +11 -3
  207. data/lib/starter_web/pages/public/blog/navigator/archive/tagview.html +11 -3
  208. data/lib/starter_web/pages/public/legal/de/300_privacy.adoc +28 -30
  209. data/lib/starter_web/pages/public/legal/en/300_privacy.adoc +28 -30
  210. data/lib/starter_web/pages/public/previewer/bootstrap_theme.adoc +3 -3
  211. data/lib/starter_web/pages/public/start/downloads/quickstarter/100_linux_starter.adoc +1 -1
  212. data/lib/starter_web/pages/public/start/{read_me_first.adoc → whats_up.adoc} +4 -4
  213. data/lib/starter_web/utilsrv/_defaults/dot.env +1 -1
  214. data/lib/starter_web/utilsrv/package.json +21 -6
  215. data/lib/starter_web/utilsrv/server.js +106 -80
  216. metadata +101 -51
  217. data/lib/starter_web/assets/themes/j1/core/js/adapter/iframer.js +0 -101
  218. data/lib/starter_web/assets/themes/j1/core/js/adapter/lightbox.js +0 -96
  219. data/lib/starter_web/assets/themes/j1/core/js/adapter/logger.js +0 -155
  220. data/lib/starter_web/assets/themes/j1/core/js/adapter/scroller.js +0 -113
  221. data/lib/starter_web/assets/themes/j1/core/js/adapter/searcher.js +0 -127
  222. data/lib/starter_web/assets/themes/j1/core/js/adapter/stickybits.js +0 -99
  223. data/lib/starter_web/assets/themes/j1/core/js/adapter/switcher.js +0 -117
  224. data/lib/starter_web/assets/themes/j1/extensions/cookiebar/js/j1cookiebar.js +0 -112
  225. data/lib/starter_web/assets/themes/j1/extensions/justified_gallery/js/j1_adapter_justified_gallery.js +0 -262
@@ -0,0 +1,1548 @@
1
+ # RuboCops - Documentation
2
+ # ------------------------------------------------------------------------------
3
+ # See: https://rubocop.readthedocs.io/en/latest/
4
+
5
+ # RuboCops - Disabled Cops
6
+ # ------------------------------------------------------------------------------
7
+ # rubocop:disable Metrics/BlockLength
8
+ # rubocop:disable Metrics/ClassLength
9
+ # rubocop:disable Metrics/LineLength
10
+ # rubocop:disable Style/StringLiterals
11
+ # rubocop:disable Style/Documentation
12
+ # rubocop:disable Metrics/BlockNesting
13
+ # rubocop:disable Layout/ClosingParenthesisIndentation
14
+ # rubocop:disable Layout/LeadingCommentSpace
15
+ # rubocop:disable Layout/EmptyLines
16
+ # rubocop:disable Layout/EmptyLinesAroundBlockBody
17
+ # rubocop:disable Layout/FirstParameterIndentation
18
+ # rubocop:disable Layout/CommentIndentation
19
+ # rubocop:disable Layout/AlignParameters
20
+ # rubocop:disable Layout/AlignHash
21
+ # rubocop:disable Layout/TrailingWhitespace
22
+ # rubocop:disable Layout/IndentHash
23
+ # rubocop:disable Layout/SpaceAroundOperators
24
+ # rubocop:disable Layout/ExtraSpacing
25
+ # rubocop:disable Style/UnlessElse
26
+ # rubocop:disable Style/HashSyntax
27
+
28
+
29
+ # ------------------------------------------------------------------------------
30
+ # ~/lib/j1_auth_manager/auth_manager/.rb
31
+ #
32
+ # Provides authentication services based on Warden|OmniAuth
33
+ #
34
+ # Product/Info:
35
+ # https://jekyll.one
36
+ #
37
+ # Copyright (C) 2019 Juergen Adams
38
+ #
39
+ # J1 Template is licensed under the MIT License.
40
+ # See: https://github.com/jekyll-one-org/j1_template/blob/master/LICENSE
41
+ #
42
+ # ------------------------------------------------------------------------------
43
+ # NOTES
44
+ #
45
+ # ------------------------------------------------------------------------------
46
+ # frozen_string_literal: true
47
+
48
+ module J1App
49
+ class AuthManager < Sinatra::Base
50
+
51
+ include J1App::Helpers
52
+ include J1App::GithubHelpers
53
+
54
+ # ==========================================================================
55
+ # Sinatra Framework settings
56
+ # ==========================================================================
57
+
58
+ # NOTE: https://stackoverflow.com/questions/7847536/sinatra-in-facebook-iframe
59
+ #
60
+ #set :protection, :except => :frame_options
61
+
62
+ # Check: http://sinatrarb.com/intro.html
63
+ #
64
+ #set :static_cache_control, [:public, :max_age => 10]
65
+
66
+
67
+ # ==========================================================================
68
+ # Base App and Warden Framework settings
69
+ # ==========================================================================
70
+
71
+ session_data = {}
72
+
73
+ # user_state_data = {
74
+ # :authenticated => 'false',
75
+ # :requested_page => '/',
76
+ # :user_name => 'unknown',
77
+ # :users_allowed => 'unknown',
78
+ # :user_id => 'unknown',
79
+ # :provider => 'unknown',
80
+ # :provider_url => '/',
81
+ # :payment_info => 'unknown',
82
+ # :permissions => 'unknown',
83
+ # :writer => 'middleware'
84
+ # }
85
+
86
+ user_state_data = {
87
+ :authenticated => 'false',
88
+ :requested_page => '/',
89
+ :user_name => 'visitor',
90
+ :users_allowed => 'all',
91
+ :user_id => 'unknown',
92
+ :provider => 'j1',
93
+ :provider_membership => 'guest',
94
+ :provider_url => 'https://jekyll.one',
95
+ :payment_info => 'unknown',
96
+ :provider_permissions => 'public',
97
+ :creator => 'middleware',
98
+ :writer => 'middleware',
99
+ :mode => 'app'
100
+ }
101
+
102
+ # Enable SSL for the rack session if configured
103
+ # --------------------------------------------------------------------------
104
+ require 'rack-ssl-enforcer' if J1App.ssl?
105
+ use Rack::SslEnforcer if J1App.ssl?
106
+
107
+ # Set the session cookie used by Rack to track all relevant data
108
+ # for the authentication service
109
+ # --------------------------------------------------------------------------
110
+ use Rack::Session::Cookie,
111
+ http_only: true, # if set to 'true', make session cookie visible to the browser (document) for HTTP
112
+ key: 'j1.app.session',
113
+ secret: ENV['J1_SESSION_SECRET'] || SecureRandom.hex
114
+
115
+ # use Rack::Cache do |config|
116
+ # #
117
+ # # ------------------------------------------------------------------------
118
+ # config.middleware.delete(Rack::Cache)
119
+ # end
120
+
121
+ # ==========================================================================
122
+ # Warden Framework initialisation
123
+ # ==========================================================================
124
+
125
+ # Define what (user) data should be put (serialized) into the session
126
+ # on requests and responses from Rack environment into the warden
127
+ # environment (env['warden']).
128
+ # --------------------------------------------------------------------------
129
+ Warden::Manager.serialize_into_session do |user|
130
+ user
131
+ end
132
+ Warden::Manager.serialize_from_session do |user|
133
+ user
134
+ end
135
+
136
+ # ==========================================================================
137
+ # OmniAuth|Warden Framework initialisation
138
+ # ==========================================================================
139
+
140
+ # Set the 'default' authentication strategy and exception handler
141
+ # (for warden) if the user was not explicitly signed in (signin dialog).
142
+ # If 'signin' fails, the default exception 'signin_failure' is thrown
143
+ # (used for all OmniAuth strategies registered).
144
+ # --------------------------------------------------------------------------
145
+ signin_failure = ->(_e) { Rack::Response.new("Can't login", 401).finish }
146
+ use Warden::Manager do |config|
147
+ # OmniAuth strategies are name-spaced by 'omni' (see: warden_omniauth.rb)
148
+ # ------------------------------------------------------------------------
149
+ config.default_strategies :"omni_#{J1App.default_provider}"
150
+ config.failure_app = signin_failure
151
+ end
152
+
153
+ use OmniAuth::Builder do |config|
154
+ # Rescue OmniAuth::Strategies::OAuth2::CallbackError
155
+ # ------------------------------------------------------------------------
156
+ config.on_failure do
157
+ new_path = '/redirect_on_failure'
158
+ Rack::Response.new(['302 Moved'], 302, 'Location' => new_path).finish
159
+ end
160
+
161
+ # Detect and set supported authentication strategies for OmniAuth
162
+ # ------------------------------------------------------------------------
163
+
164
+ # Additional (strategy) option skip_extra, default: true
165
+ #
166
+ # If true, skips the collection of raw data (extra) to NOT blow
167
+ # up the session cookie (as it is limited to 4K)
168
+ skip_extra = true
169
+
170
+ if J1App.active_providers.include? 'patreon'
171
+ scope = J1App.auth_config['providers']['patreon']['scope'].join(',')
172
+ data_collection = J1App.auth_config['providers']['patreon']['data_fields'].join(',')
173
+ skip_extra = false if data_collection =~ /raw/i
174
+ provider :patreon,
175
+ ENV['PATREON_CLIENT_ID'],
176
+ ENV['PATREON_CLIENT_SECRET'],
177
+ scope: "#{scope}",
178
+ skip_extra: skip_extra
179
+ end
180
+ if J1App.active_providers.include? 'disqus'
181
+ scope = J1App.auth_config['providers']['disqus']['scope'].join(',')
182
+ data_collection = J1App.auth_config['providers']['disqus']['data_fields'].join(',')
183
+ skip_extra = false if data_collection =~ /raw/i
184
+ provider :disqus,
185
+ ENV['DISQUS_CLIENT_ID'],
186
+ ENV['DISQUS_CLIENT_SECRET'],
187
+ scope: "#{scope}",
188
+ skip_extra: skip_extra
189
+ end
190
+ if J1App.active_providers.include? 'facebook'
191
+ scope = J1App.auth_config['providers']['facebook']['scope'].join(',')
192
+ data_collection = J1App.auth_config['providers']['facebook']['data_fields'].join(',')
193
+ skip_extra = false if data_collection =~ /raw/i
194
+ provider :facebook,
195
+ ENV['FACEBOOK_CLIENT_ID'],
196
+ ENV['FACEBOOK_CLIENT_SECRET'],
197
+ scope: "#{scope}",
198
+ skip_extra: skip_extra
199
+ end
200
+ if J1App.active_providers.include? 'github'
201
+ scope = J1App.auth_config['providers']['github']['scope'].join(',')
202
+ data_collection = J1App.auth_config['providers']['github']['data_fields'].join(',')
203
+ skip_extra = false if data_collection =~ /raw/i
204
+ provider :github,
205
+ ENV['GITHUB_CLIENT_ID'],
206
+ ENV['GITHUB_CLIENT_SECRET'],
207
+ scope: "#{scope}",
208
+ skip_extra: skip_extra
209
+ end
210
+ if J1App.active_providers.include? 'twitter'
211
+ scope = J1App.auth_config['providers']['twitter']['scope'].join(',')
212
+ data_collection = J1App.auth_config['providers']['twitter']['data_fields'].join(',')
213
+ skip_extra = false if data_collection =~ /raw/i
214
+ provider :twitter,
215
+ ENV['TWITTER_CLIENT_ID'],
216
+ ENV['TWITTER_CLIENT_SECRET'],
217
+ scope: "#{scope}",
218
+ skip_extra: skip_extra
219
+ end
220
+ end
221
+
222
+ # Set the (internal) endpoint if a user is successfully authenticated
223
+ # --------------------------------------------------------------------------
224
+ use J1WardenOmniAuth do |config|
225
+ config.redirect_after_callback = '/post_authentication'
226
+ end
227
+
228
+ # Add the internal logger from Rack to the middleware's of the stack
229
+ # --------------------------------------------------------------------------
230
+ use Rack::Logger
231
+
232
+ # Load user profiles, permissions, conditions and strategies
233
+ # --------------------------------------------------------------------------
234
+
235
+ providers = J1App.auth_config['providers']
236
+ permissions = J1App.permissions
237
+
238
+
239
+ # ==========================================================================
240
+ # Sinatra (before) FILTER to preprocess all page requests
241
+ # ==========================================================================
242
+
243
+ # Prepare root (index) page for app detection
244
+ #
245
+ before '/' do
246
+ log_info! "ROOT", "Prepare", 'Page access'
247
+
248
+ # read existing/current cookie 'j1.user.state' to update all data
249
+ # of user_state_data (hash) otherwise set initial data
250
+ # ------------------------------------------------------------------------
251
+ unless env['HTTP_COOKIE'] == nil
252
+ log_info! "ROOT", 'Cookie', 'Read current user state data'
253
+ user_state_data = readCookie('j1.user.state')
254
+ data_json = user_state_data.to_json
255
+ #data_json = JSON.pretty_generate(user_state_data)
256
+ #log_info! "ROOT", 'Cookie', 'Current user state data', "#{data_json}"
257
+
258
+ # if env['HTTP_COOKIE'].include? 'j1.user.state'
259
+ # session_encoded = request.cookies['j1.user.state']
260
+ # session_decoded = Base64.decode64(session_encoded)
261
+ # user_state_data = JSON.parse(session_decoded)
262
+ # end
263
+
264
+ else
265
+ requested_page = env['REQUEST_URI']
266
+ session_data['requested_page'] = "#{env['REQUEST_URI']}"
267
+ end
268
+
269
+ # Create|Initialize the J1 web session cookie
270
+ # ------------------------------------------------------------------------
271
+ if warden.authenticated?
272
+ # log_info! "ROOT", 'Cookie', 'Update current user data'
273
+
274
+ user = warden.user
275
+ log_info! "ROOT", 'AuthCheck', 'User detected', "#{user[:provider]}"
276
+ log_info! "ROOT", 'AuthCheck', 'User detected as signed in'
277
+ session_data['authenticated'] = 'true'
278
+ session_data['requested_page'] = '/'
279
+ session_data['user_name'] = user[:info]['nickname']
280
+ session_data['users_allowed'] = providers["#{user[:provider]}"]['users']
281
+ session_data['user_id'] = user[:uid]
282
+ session_data['provider'] = user[:provider]
283
+ session_data['provider_membership'] = 'member'
284
+ session_data['provider_url'] = providers["#{user[:provider]}"]['provider_url']
285
+ session_data['provider_permissions'] = providers["#{user[:provider]}"]['permissions']
286
+ session_data['payment_status'] = user[:info][:payment_status]
287
+ else
288
+ log_info! "ROOT", 'AuthCheck', 'User detected', 'signed out'
289
+ session_data['authenticated'] = 'false'
290
+ # session_data['requested_page'] = '/'
291
+ session_data['users_allowed'] = 'all'
292
+ session_data['user_name'] = 'visitor'
293
+ session_data['user_id'] = 'unknown'
294
+ session_data['payment_status'] = 'unknown'
295
+ session_data['provider'] = 'j1'
296
+ session_data['provider_membership'] = 'guest'
297
+ session_data['provider_url'] = 'https://jekyll.one'
298
+ session_data['provider_permissions'] = 'public'
299
+ end
300
+ session_data['writer'] = 'middleware'
301
+ session_data['creator'] = 'middleware'
302
+
303
+ user_state_data = merge( user_state_data, session_data )
304
+
305
+ data_json = session_data.to_json
306
+ #data_json = JSON.pretty_generate(session_data)
307
+ # log_info! "ROOT", 'Cookie', 'Current user state data', "#{data_json}"
308
+
309
+ # data_json = user_state_data.to_json
310
+ # log_info! "ROOT", 'Cookie', 'Update user state data', "#{data_json}"
311
+ # writeCookie('j1.user.state', data_json)
312
+ end
313
+
314
+ # General content (type) detection (auth pre-flight)
315
+ # --------------------------------------------------------------------------
316
+ before '/(apps|pages|posts)/*' do
317
+
318
+ log_info! 'AuthManager', 'PreFlight', 'Initial checks initiated'
319
+
320
+ # read existing/current cookie 'j1.user.state'
321
+ # to update all data of user_state_data (hash)
322
+ # if request.warden.user.respond_to?(:info)
323
+ # ------------------------------------------------------------------------
324
+
325
+ #user_state_data = readCookie('j1.user.state')
326
+
327
+ if env['HTTP_COOKIE'].include? 'j1.user.state'
328
+ session_encoded = request.cookies['j1.user.state']
329
+ session_decoded = Base64.decode64(session_encoded)
330
+ # See: https://stackoverflow.com/questions/86653/how-can-i-pretty-format-my-json-output-in-ruby-on-rails
331
+ session_pretty = JSON.pretty_generate(session_decoded)
332
+ user_state_data = JSON.parse(session_decoded)
333
+
334
+ log_info! 'PreFlight', 'Cookie', 'Read user state data' #, "#{session_decoded}" # ,"#{session_pretty}"
335
+ else
336
+ requested_page = env['REQUEST_URI']
337
+ session_data['requested_page'] = "#{env['REQUEST_URI']}"
338
+ end
339
+
340
+ # Create|Initialize the J1 web session cookie
341
+ # ------------------------------------------------------------------------
342
+ log_info! 'PreFlight', 'AuthCheck', 'Check authentication state'
343
+ if warden.authenticated?
344
+ user = warden.user
345
+ session_data['authenticated'] = 'true'
346
+ session_data['user_name'] = user[:info]['nickname']
347
+ session_data['user_id'] = user[:uid]
348
+ session_data['provider'] = user[:provider]
349
+ session_data['provider_url'] = providers["#{user[:provider]}"]['provider_url']
350
+ session_data['users_allowed'] = providers["#{user[:provider]}"]['users']#
351
+ session_data['provider_permissions'] = providers["#{user[:provider]}"]['permissions']
352
+ session_data['provider_membership'] = 'member'
353
+ session_data['payment_status'] = user[:info][:payment_status]
354
+ session_data['writer'] = 'middleware'
355
+
356
+ user_state_data = merge( user_state_data, session_data )
357
+ log_info! 'PreFlight', 'AuthCheck', 'User authenticated', "#{user[:info]['nickname']}"
358
+
359
+ # session_json = user_state_data.to_json
360
+ # log_info! 'PreFlight', 'Cookie', 'Write web session data', "#{session_json}"
361
+ # writeCookie('j1.user.state', session_json)
362
+
363
+ end
364
+
365
+ # User state|content detection for implicit authentication
366
+ # ------------------------------------------------------------------------
367
+ log_info! 'PreFlight', 'CheckConfig', 'Authentication check', 'disabled' if authentication_enabled? == false
368
+ log_info! 'PreFlight', 'AuthCheck', 'Pass for all pages' if authentication_enabled? == false
369
+ pass if authentication_enabled? == false
370
+
371
+ log_info! 'PreFlight', 'CheckConfig', 'Authentication check', 'enabled'
372
+ log_info! 'PreFlight', 'DetectContent', 'Public content detected' if public_content?
373
+ log_info! 'PreFlight', 'DetectContent', 'Pass all public content' if public_content?
374
+ pass if public_content?
375
+
376
+ log_info! 'PreFlight', 'DetectCookieConsent', 'Cookie Consent', "#{user_state_data['cookies_accepted']}"
377
+
378
+ # if user_state_data['cookies_accepted'] === 'declined'
379
+ # requested_page = env['REQUEST_URI']
380
+ # requested_page.scan(/(protected|private)/) do |match|
381
+ # category = match[0]
382
+ # log_info! 'PreFlight', 'DetectContent', 'Content detected as', "#{category}"
383
+ # log_info! 'PreFlight', 'Redirect', 'Pass to dialog page (Cookie Consent)'
384
+ # description_title = "Cookie consent declined"
385
+ # redirect "/cookie_consent?provider=#{user_state_data['provider']}&user=#{user_state_data['user_name']}&category=#{category}&requested_page=#{requested_page}&title=#{description_title}"
386
+ # #redirect requested_page
387
+ # end
388
+ # end
389
+
390
+ log_info! 'PreFlight', 'DetectContent', 'Check content type'
391
+
392
+ requested_page = env['REQUEST_URI']
393
+ requested_page.scan(/(protected|private)/) do |match|
394
+
395
+ category = match[0]
396
+ log_info! 'PreFlight', 'DetectContent', 'Content type', "#{category}"
397
+
398
+ log_info! 'PreFlight', 'AuthCheck', 'Check authorisation status'
399
+ if warden.authenticated?
400
+ user_name = user[:info]['nickname']
401
+ log_info! 'PreFlight', 'AuthCheck', 'User detected', "#{user_name}"
402
+
403
+ current_provider = warden.user[:provider]
404
+
405
+ # provider_strategy = strategies["#{default_provider}"]
406
+ strategy = providers["#{current_provider}"]['strategy']
407
+ provider_strategy = :"#{strategy}"
408
+
409
+ user_state_data['user_name'] = user_name
410
+ user_state_data['provider_url'] = providers["#{current_provider}"]['provider_url']
411
+ user_state_data['users_allowed'] = providers["#{current_provider}"]['users']
412
+ user_state_data['provider_permissions'] = providers["#{user[:provider]}"]['permissions']
413
+ user_state_data['requested_page'] = requested_page
414
+
415
+ log_info! 'PreFlight', 'ContentCheck', 'Check permissions'
416
+ if permissions[:"#{category}"].include? current_provider
417
+ log_info! 'PreFlight', 'ContentCheck', 'Provider detected', "#{current_provider}"
418
+ log_info! 'PreFlight', 'ContentCheck', 'Category detected', "#{category}"
419
+ log_info! 'PreFlight', 'ContentCheck', 'Category support', 'enabled'
420
+
421
+ # Check permissions
422
+ #
423
+ #log_info! 'Authorisation', 'ConditionCheck', 'Check permissions for provider', "#{current_provider}"
424
+ #conditions = J1App.conditions current_provider
425
+ # if conditions["#{category}"]
426
+ # log_info! 'Authorisation', 'ConditionCheck', 'Conditions detected', "#{category}"
427
+ # conditions["#{category}"].each do |k, v|
428
+ # case k
429
+ # when 'enabled'
430
+ # log_info! 'Authorisation', 'ConditionCheck', "#{k}", "#{v}"
431
+ # when 'users'
432
+ # log_info! 'Authorisation', 'ConditionCheck', 'users'
433
+ # v.each do |k, v|
434
+ # log_info! 'Authorisation', 'ConditionCheck', "users - #{k}", "#{v}"
435
+ # end
436
+ # when 'payment'
437
+ # log_info! 'Authorisation', 'ConditionCheck', 'payment'
438
+ # v.each do |k, v|
439
+ # case k
440
+ # when 'tiers'
441
+ # log_info! 'Authorisation', 'ConditionCheck', "payment - #{k}", "#{v}"
442
+ # when 'tier'
443
+ # v.each do |k, v|
444
+ # log_info! 'Authorisation', 'ConditionCheck', 'payment - tiers - tier : ' "#{k}", "#{v}"
445
+ # end
446
+ # end
447
+ # end
448
+ # end
449
+ # end
450
+ # end
451
+ else
452
+ provider = permissions[:"#{category}"][0]
453
+ log_info! 'PreFlight', 'ContentCheck', 'Provider detected', "#{current_provider}"
454
+ log_info! 'PreFlight', 'ContentCheck', 'Category detected', "#{category}"
455
+ log_info! 'PreFlight', 'ContentCheck', 'Category supported', 'NO'
456
+ log_info! 'PreFlight', 'AuthCheck', 'Authorisation failed for user', "#{user_name}"
457
+
458
+ log_info! 'PreFlight', 'SignOut', 'Sign out user', "#{user_name}"
459
+ warden.logout
460
+ session.clear
461
+
462
+ session_json = user_state_data.to_json
463
+ log_info! 'PreFlight', 'Cookie', 'Write web session data', "#{session_json}"
464
+
465
+ session_encoded = Base64.encode64(session_json)
466
+ response.set_cookie(
467
+ 'j1.user.state',
468
+ domain: false,
469
+ value: session_encoded.to_s,
470
+ path: '/'
471
+ )
472
+
473
+ log_info! 'PreFlight', 'Redirect', 'Call API request', 'PageValidate'
474
+ allowed_users = providers["#{provider}"]['users'].join(',')
475
+ redirect "/page_validation?provider=#{provider}&category=#{category}&page=#{requested_page}&allowed_users=#{allowed_users}"
476
+ end
477
+
478
+ time = Time.now.ctime.to_s
479
+ log_info! 'PreFlight', 'AuthCheck', 'Pass to requested page', "#{requested_page}"
480
+ log_info! 'PreFlight', 'AuthCheck', 'Set X-Response-Headers'
481
+
482
+ # See: https://stackoverflow.com/questions/10438276/how-to-disable-static-file-caching-in-rails-3-thin-on-windows
483
+ # response.headers["Cache-Control"] = 'no-cache, no-store, max-age=0, must-revalidate'
484
+ # response.headers["Pragma"] = 'no-cache'
485
+ # response.headers["Expires"] = 'Fri, 01 Jan 1990 00:00:00 GMT'
486
+ # response.headers['X-J1-AuthManager'] = "page-validated;category=#{category};called=" + time
487
+ pass
488
+ else
489
+ log_info! 'PreFlight', 'AuthCheck', 'User detected', 'signed out'
490
+ default_provider = permissions[:"#{category}"][0]
491
+ log_info! 'PreFlight', 'AuthCheck', 'Set default provider', "#{default_provider}"
492
+
493
+ strategy = providers["#{default_provider}"]['strategy']
494
+ provider_strategy = :"#{strategy}"
495
+
496
+ log_info! 'PreFlight', 'AuthCheck', 'Start processing provider', "#{default_provider}"
497
+ log_info! 'PreFlight', 'AuthCheck', 'Authentication strategy', "#{provider_strategy}"
498
+
499
+ case provider_strategy
500
+
501
+ when :org
502
+ warden.authenticate!
503
+ github_organization_authenticate! ENV['GITHUB_ORG_NAME']
504
+ logger.info "Hi There, #{user_state_data[:user_name]}! You have access to the #{params['id']} organization"
505
+
506
+ when :team
507
+ warden.authenticate!
508
+ github_team_authenticate! ENV['GITHUB_TEAM_ID']
509
+ logger.info "Hi There, #{user_state_data[:user_name]}! You have access to the #{params['id']} team"
510
+
511
+ when :teams
512
+ warden.authenticate!
513
+ github_teams_authenticate! ENV['GITHUB_TEAM_IDS'].split(',')
514
+ logger.info "Hi There, #{user_state_data[:user_name]}! You have access to the #{params['id']} team"
515
+
516
+ when :member
517
+ log_info! 'PreFlight', 'AuthCheck', 'Process authentication strategy'
518
+
519
+ if env['HTTP_COOKIE'].include? 'j1.user.state'
520
+ session_encoded = request.cookies['j1.user.state']
521
+ session_decoded = Base64.decode64(session_encoded)
522
+ log_info! 'PreFlight', 'Cookie', 'Read user state data' # "#{session_decoded}"
523
+ user_state_data = JSON.parse(session_decoded)
524
+ end
525
+
526
+ # Update cookie data
527
+ # ----------------------------------------------------------------------
528
+ user_state_data['provider_url'] = providers["#{default_provider}"]['provider_url']
529
+ user_state_data['users_allowed'] = providers["#{default_provider}"]['users']
530
+ user_state_data['provider_permissions'] = providers["#{default_provider}"]['permissions']
531
+ user_state_data['requested_page'] = env['REQUEST_URI']
532
+ user_state_data['writer'] = 'middleware'
533
+
534
+ # write updated J1 session cookie
535
+ #
536
+ # session_json = user_state_data.to_json
537
+ # log_info! 'PreFlight', 'Cookie', 'Write web session data', "#{session_json}"
538
+ # writeCookie('j1.user.state', session_json)
539
+
540
+ log_info! 'PreFlight', 'Redirect', 'Call API request', 'PageValidate'
541
+
542
+ allowed_users = providers["#{default_provider}"]['users'].join(',')
543
+ requested_page = env['REQUEST_URI']
544
+ redirect "/page_validation?provider=#{default_provider}&category=#{category}&page=#{requested_page}&allowed_users=#{allowed_users}"
545
+ else
546
+ raise J1App::ConfigError
547
+ end
548
+
549
+ end
550
+ end
551
+ end
552
+
553
+
554
+ # ==========================================================================
555
+ # API ENDPOINTS (Sinatra HANDLERS)
556
+ # ==========================================================================
557
+
558
+ # ENDPOINT authentication (called from WEB by auth client)
559
+ # --------------------------------------------------------------------------
560
+ get '/authentication' do
561
+ # collect (common) GET parameter|s
562
+ #
563
+ request = params.fetch('request')
564
+ provider = params.fetch('provider')
565
+
566
+ log_info! 'API', 'Authentication', 'Authentication request received'
567
+
568
+ # SignIn
569
+ # ------------------------------------------------------------------------
570
+ if request === 'signin'
571
+
572
+ log_info! 'Authentication', 'SignIn', 'Called for provider', "#{provider}"
573
+
574
+ # collect (additional) GET parameter|s
575
+ # ----------------------------------------------------------------------
576
+ allowed_users = params.fetch('allowed_users')
577
+
578
+ user_state_data['users_allowed'] = allowed_users
579
+ user_state_data['writer'] = 'middleware'
580
+
581
+ # Write updated J1 session data to cookie
582
+ # --------------------------------------------------------------------
583
+ # session_json = user_state_data.to_json
584
+ # log_info! 'Authentication', 'Cookie', 'Write web session data', "#{session_json}"
585
+ #
586
+ # session_encoded = Base64.encode64(session_json)
587
+ # response.set_cookie(
588
+ # 'j1.user.state',
589
+ # domain: false,
590
+ # value: session_encoded.to_s,
591
+ # path: '/'
592
+ # )
593
+
594
+ if warden.authenticated?
595
+ log_info! 'Authentication', 'SignIn', 'User already signed in', "#{warden.user[:info]['nickname']}"
596
+ requested_page = user_state_data['requested_page']
597
+ log_info! 'Authentication', 'SignIn', 'Pass user for requested page', "#{requested_page}"
598
+ redirect "#{requested_page}"
599
+ else
600
+ log_info! 'Authentication', 'SignIn', 'Initiate OmniAuth authentication'
601
+
602
+ # Make (really) sure that old session is cleared before login
603
+ # --------------------------------------------------------------------
604
+ warden.logout
605
+ session.clear
606
+ warden.authenticate! :"omni_#{provider}"
607
+ end
608
+ # SignOut
609
+ # ------------------------------------------------------------------------
610
+ elsif request === 'signout'
611
+ # collect (additional) GET parameter|s
612
+ provider_signout = params.fetch('provider_signout')
613
+ log_info! 'Authentication', 'SignOut', 'Called for provider', #{provider}"
614
+
615
+ if warden.authenticated?
616
+ user = warden.user[:info]['nickname']
617
+ provider = warden.user[:provider]
618
+ provider_url = user_state_data['provider_url']
619
+ log_info! 'Authentication', 'SignOut', 'Sign out user', "#{user}"
620
+ warden.logout
621
+ session.clear
622
+
623
+ # Read current J1 web session cookie
624
+ # --------------------------------------------------------------------
625
+ if env['HTTP_COOKIE'].include? 'j1.user.state'
626
+ session_encoded = env['rack.request.cookie_hash']['j1.user.state']
627
+ session_decoded = Base64.decode64(session_encoded)
628
+ log_info! 'Authentication', 'Cookie', 'Read user state data' # #{session_decoded}"
629
+ user_state_data = JSON.parse(session_decoded)
630
+ else
631
+ user_state_data['requested_page'] = env['REQUEST_URI']
632
+ end
633
+
634
+ # Update J1 web session data
635
+ # --------------------------------------------------------------------
636
+ # user_state_data['user_name'] = 'visitor'
637
+ # user_state_data['user_id'] = 'unknown'
638
+ # user_state_data['users_allowed'] = 'all'
639
+ # user_state_data['payment_status'] = 'unknown'
640
+ # user_state_data['provider'] = 'j1'
641
+ # user_state_data['provider_url'] = 'https://jekyll.one'
642
+ # user_state_data['provider_membership'] = 'guest'
643
+ # user_state_data['provider_permissions'] = 'public'
644
+ # user_state_data['authenticated'] = 'false'
645
+ # user_state_data['writer'] = 'middleware'
646
+
647
+ # Write updated J1 session data to cookie
648
+ # --------------------------------------------------------------------
649
+ # session_json = user_state_data.to_json
650
+ # log_info! 'Authentication', 'SignOut', 'Write web session data', "#{session_json}"
651
+ # writeCookie('j1.user.state', session_json)
652
+
653
+ if provider_signout === 'true'
654
+ log_info! 'Authentication', 'SignOut', 'Sign out user', "#{user}"
655
+ log_info! 'Authentication', 'SignOut', 'Sign out from', "#{provider}"
656
+ log_info! 'Authentication', 'Redirect', 'Pass to provider', "#{provider_url}"
657
+ redirect "#{provider_url}"
658
+ else
659
+ log_info! 'Authentication', 'SignOut', 'Sign out user', "#{user}"
660
+ log_info! 'Authentication', 'SignOut', 'Sign out from', "session"
661
+
662
+ # If signed out, redirect ONLY for PUBLIC pages
663
+ # ------------------------------------------------------------------
664
+ if redirect_whitelisted?user_state_data['requested_page']
665
+ log_info! 'Authentication', 'Redirect', 'Pass to page', "#{user_state_data['requested_page']}"
666
+ redirect user_state_data['requested_page']
667
+ else
668
+ log_info! 'Authentication', 'Redirect', 'Redirect NOT whitelisted'
669
+ log_info! 'Authentication', 'Redirect', 'Pass to page', "/"
670
+ redirect '/'
671
+ end
672
+ end
673
+ else
674
+ # THIS condition should NEVER REACHED because NO logout dialog
675
+ # (modal) is provided by the auth client if a user isn't signed in.
676
+ # Kept this alternative for cases something went wrong.
677
+ # --------------------------------------------------------------------
678
+ log_info! 'Authentication', 'API', 'DEAD PATH: Called for sign out', 'NOT signed in'
679
+
680
+ # Read current J1 session cookie
681
+ # --------------------------------------------------------------------
682
+ if env['HTTP_COOKIE'].include? 'j1.user.state'
683
+ session_encoded = env['rack.request.cookie_hash']['j1.user.state']
684
+ session_decoded = Base64.decode64(session_encoded)
685
+ user_state_data = JSON.parse(session_decoded)
686
+
687
+ log_info! 'Authentication', 'Cookie', 'DEAD PATH. Read user state data' # #{session_decoded}"
688
+ else
689
+ user_state_data['requested_page'] = env['REQUEST_URI']
690
+ end
691
+
692
+ # Update J1 web session data
693
+ # --------------------------------------------------------------------
694
+ # user_state_data['user_name'] = 'visitor'
695
+ # user_state_data['user_id'] = 'unknown'
696
+ # user_state_data['users_allowed'] = 'all'
697
+ # user_state_data['payment_status'] = 'unknown'
698
+ # user_state_data['provider'] = 'j1'
699
+ # user_state_data['provider_url'] = 'https://jekyll.one'
700
+ # user_state_data['provider_membership'] = 'guest'
701
+ # user_state_data['provider_permissions'] = 'public'
702
+ # user_state_data['provider_membership'] = 'member'
703
+ # user_state_data['authenticated'] = 'false'
704
+ # user_state_data['writer'] = 'middleware'
705
+
706
+ # Write updated J1 session data to cookie
707
+ # --------------------------------------------------------------------
708
+ # session_json = user_state_data.to_json
709
+ # log_info! 'Authentication', 'Cookie', 'DEAD PATH. Write web session data', "#{session_json}"
710
+ # writeCookie('j1.user.state', session_json)
711
+
712
+ log_info! 'Post Authentication', 'Redirect', 'DEAD PATH: Pass to requested page', "#{user_state_data['requested_page']}"
713
+ redirect user_state_data['requested_page']
714
+ end
715
+ else
716
+ raise J1App::ConfigError
717
+ end
718
+ end
719
+ # END: get '/authentication'
720
+ # --------------------------------------------------------------------------
721
+
722
+ # ENDPOINT post_authentication (called after a user is back from OAuth Provider)
723
+ # --------------------------------------------------------------------------
724
+ get '/post_authentication' do
725
+ reward = {
726
+ :id => 'unknown',
727
+ :name => 'unknown',
728
+ :link => '#'
729
+ }
730
+ campaign = {
731
+ :id => 'unknown',
732
+ :link => '#'
733
+ }
734
+
735
+ log_info! 'API', 'Post Authentication', 'Identification request received'
736
+
737
+ log_info! 'Post Authentication', 'Cookie', 'Read user state data'
738
+ session_encoded = request.cookies['j1.user.state']
739
+ session_decoded = Base64.decode64(session_encoded)
740
+ user_state_data = JSON.parse(session_decoded)
741
+
742
+ log_info! 'Post Authentication', 'Cookie', 'Requested page read', "#{user_state_data['requested_page']}"
743
+
744
+ user = warden.user
745
+ user_json = user.to_json
746
+
747
+ if user[:provider] === 'disqus'
748
+ user[:info][:urls][:site] = "https://disqus.com"
749
+ user[:info][:urls][:home] = user[:info]['urls']['profileUrl']
750
+ user[:info][:urls][:blog] = "https://disqus.com/by/juergen_adams/"
751
+ user[:info][:urls][:member] = user[:info]['urls']['profileUrl']
752
+ end
753
+
754
+ if user[:provider] === 'github'
755
+ user[:info][:urls][:site] = "https://github.com"
756
+ user[:info][:urls][:home] = user[:info]['urls']['GitHub']
757
+ user[:info][:urls][:blog] = "https://github.com/jekyll-one"
758
+ user[:info][:urls][:member] = user[:info]['urls']['Blog']
759
+ end
760
+
761
+ if user[:provider] === 'patreon'
762
+
763
+ user[:info][:urls][:site] = "https://patreon.com"
764
+ user[:info][:urls][:home] = "https://patreon.com/home"
765
+ user[:info][:urls][:blog] = "https://patreon.com/jekyll_one"
766
+
767
+ unless user[:info]['payment_info'].empty?
768
+ reward_url = user[:info]['payment_info']['relationships']['reward']['links']['related']
769
+ reward_json = RestClient.get "#{reward_url}", {:content_type => :json, :accept => :json}
770
+ reward_data = JSON.parse(reward_json)
771
+ user[:info][:urls][:member] = "https://patreon.com" + reward_data['data']['attributes']['url']
772
+ user[:info][:payment_status] = user[:info]['payment_info']['attributes']['declined_since'].nil? ? 'true' : 'false'
773
+ else
774
+ reward_url = ""
775
+ reward_json = ""
776
+ reward_data = ""
777
+ user[:info][:payment_status] = 'false'
778
+ end
779
+
780
+ unless reward_data.empty?
781
+ reward[:id] = reward_data['data']['id']
782
+ reward[:name] = reward_data['data']['attributes']['title']
783
+ reward[:link] = "https://patreon.com" + reward_data['data']['attributes']['url']
784
+ campaign[:id] = reward_data['data']['relationships']['campaign']['data']['id']
785
+ campaign[:link] = reward_data['data']['relationships']['campaign']['links']['related']
786
+ else
787
+ reward[:id] = ""
788
+ reward[:name] = "no tiers"
789
+ reward[:link] = ""
790
+ campaign[:id] = ""
791
+ campaign[:link] = ""
792
+ end
793
+ end
794
+
795
+ user[:extra][:reward] = reward
796
+ user[:extra][:campaign] = campaign
797
+
798
+ if user.nil?
799
+ # Collection of session data failed (e.g cookie > 4K)
800
+ #
801
+ log_info! 'Post Authentication', 'Identification', 'Internal error', 'User identification failed'
802
+ warden.logout
803
+ session.clear
804
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
805
+ description_title = "Access Denied"
806
+ redirect "/access_denied?provider=unknown&user=unknown&category=unknown&title=#{description_title}"
807
+ else
808
+ log_info! 'Post Authentication', 'Identification', 'User identified successfully'
809
+ user_state_data['user_name'] = user[:info]['nickname']
810
+ user_state_data['user_id'] = user[:uid]
811
+ user_state_data['provider'] = user[:provider]
812
+ user_state_data['provider_membership'] = 'member'
813
+ user_state_data['provider_permissions'] = providers["#{user[:provider]}"]['permissions']
814
+ user_state_data['users_allowed'] = providers["#{user[:provider]}"]['users']
815
+ user_state_data['authenticated'] = 'true'
816
+ user_state_data['payment_status'] = user[:info][:payment_status]
817
+ user_state_data['writer'] = 'middleware'
818
+
819
+ current_user = user[:info]['nickname'] = user[:info]['nickname']
820
+ current_provider = user[:provider]
821
+
822
+ user_state_data['requested_page'].scan(/(protected|private)/) do |match|
823
+
824
+ # Set category from requested page
825
+ #
826
+ category = match[0]
827
+ log_info! 'Post Authentication', 'Identification', 'Process content type', "#{category}"
828
+
829
+ # Check if user is allowed to access protected content in GENERAL
830
+ #
831
+ log_info! 'Post Authentication', 'Identification', 'Check for allowed users'
832
+ unless user_state_data['users_allowed'].include? 'all'
833
+ unless user_state_data['users_allowed'].include? "#{current_user}"
834
+ log_info! 'Post Authentication', 'Identification', 'User not allowed', "#{current_user}"
835
+ log_info! 'Post Authentication', 'Identification', 'Allowed users', "#{user_state_data['users_allowed']}"
836
+ log_info! 'Post Authentication', 'Identification', 'Logout user from current session', "#{current_user}"
837
+ warden.logout
838
+ session.clear
839
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
840
+ description_title = "Access Denied"
841
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
842
+ end
843
+ end
844
+ log_info! 'Post Authentication', 'Identification', 'Allowed users', "#{user_state_data['users_allowed']}"
845
+
846
+ # Check conditions to access protected content (if any)
847
+ #
848
+ log_info! 'Post Authentication', 'Identification', 'Check for conditions', "#{current_provider}"
849
+ check_conditions = providers["#{user[:provider]}"]['conditions'][category]['enabled']
850
+ if check_conditions
851
+
852
+ if providers["#{user[:provider]}"]['conditions'][category]['users']['whitelist'].nil?
853
+ category_whitelist = 'all'
854
+ else
855
+ category_whitelist = providers["#{user[:provider]}"]['conditions'][category]['users']['whitelist']
856
+ end
857
+
858
+ # Check if user is BLACKLISTED
859
+ #
860
+ blacklist = providers["#{user[:provider]}"]['conditions'][category]['users']['blacklist']
861
+ if blacklist.include? "#{current_user}"
862
+ log_info! 'Post Authentication', 'Identification', 'Check blacklisting'
863
+ log_info! 'Post Authentication', 'Identification', 'User blacklisted', "#{current_user}"
864
+ user[:info][:blacklisted] = 'true'
865
+ log_info! 'Post Authentication', 'Identification', 'Logout user from current session', "#{current_user}"
866
+ warden.logout
867
+ session.clear
868
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
869
+ description_title = "Access Denied"
870
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
871
+ end
872
+
873
+ log_info! 'Post Authentication', 'Identification', 'Check whitelisting'
874
+ if category_whitelisted? category_whitelist, current_user
875
+ user[:info][:whitelisted] = 'true'
876
+ reward[:name] = 'whitelisted'
877
+ log_info! 'Post Authentication', 'Identification', 'User whitelisted', "#{current_user}"
878
+ log_info! 'Post Authentication', 'Identification', 'Reward set to', 'Whitelisted'
879
+ else
880
+ log_info! 'Post Authentication', 'Identification', 'No whitelisting found', "#{current_user}"
881
+ end
882
+
883
+ log_info! 'Post Authentication', 'Identification', 'Check conditions'
884
+ unless category_whitelisted? category_whitelist, current_user
885
+ log_info! 'Post Authentication', 'Identification', 'Check rewards'
886
+ payment_tiers = providers["#{user[:provider]}"]['conditions'][category]['payment']['activated']
887
+ log_info! 'Post Authentication', 'Identification', 'Check rewards', "#{current_user}"
888
+ if payment_activated? payment_tiers
889
+ log_info! 'Post Authentication', 'Identification', 'Reward found', "#{reward[:name]}"
890
+
891
+ # Check if any payment exists for that user
892
+ #
893
+ log_info! 'Post Authentication', 'Identification', 'Check payment status'
894
+ if user[:info]['payment_info'].empty?
895
+ log_info! 'Post Authentication', 'Identification', 'Payment status: NOT AVAILABLE', "#{current_user}"
896
+ log_info! 'Post Authentication', 'Identification', 'Logout user from current session', "#{current_user}"
897
+ warden.logout
898
+ session.clear
899
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
900
+ description_title = "Access Denied"
901
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
902
+ end
903
+
904
+ # Check for VALID payments (scope: pledge-to-me)
905
+ #
906
+ payment_status = user[:info]['payment_info']['attributes']['declined_since']
907
+ unless payment_valid? payment_status
908
+ log_info! 'Post Authentication', 'Identification', 'Payment status INVALID', "#{current_user}"
909
+ log_info! 'Post Authentication', 'Identification', 'Logout user from current session', "#{current_user}"
910
+ warden.logout
911
+ session.clear
912
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
913
+ description_title = "Access Denied"
914
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
915
+ else
916
+ log_info! 'Post Authentication', 'Identification', 'Payment status VALID', "#{current_user}"
917
+ end
918
+ end
919
+
920
+ end
921
+ # end category_whitelisted
922
+ else
923
+ category_condition_state = providers["#{user[:provider]}"]['conditions'][category]['enabled']
924
+ log_info! 'Post Authentication', 'Identification', 'Category check failed for', "#{current_provider}"
925
+ log_info! 'Post Authentication', 'Identification', "Category checked", "#{category}"
926
+ log_info! 'Post Authentication', 'Identification', "Category support", "#{category_condition_state}"
927
+ warden.logout
928
+ session.clear
929
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
930
+ description_title = "Access Denied"
931
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
932
+ end
933
+ # end check conditions
934
+
935
+ end
936
+ # end protected content
937
+ end
938
+ # end user.nil?
939
+
940
+
941
+ # user_state_data['provider'] = current_provider
942
+ # user_state_data['users_allowed'] = providers["#{current_provider}"]['users']
943
+
944
+ # TODO: Add membership|product specific data for the SideBar
945
+
946
+ # write updated J1 session data to cookie
947
+ #
948
+ # session_json = user_state_data.to_json
949
+ # log_info! 'Post Authentication', 'Cookie', 'Write web session data', "#{session_json}"
950
+ # session_encoded = Base64.encode64(session_json)
951
+ # response.set_cookie(
952
+ # 'j1.user.state',
953
+ # domain: false,
954
+ # value: session_encoded.to_s,
955
+ # path: '/'
956
+ # )
957
+
958
+ # redirect authenticated|validated user to requested page
959
+ #
960
+ time = Time.now.ctime.to_s
961
+
962
+ log_info! 'Post Authentication', 'Identification', 'Provider', "#{user[:provider]}"
963
+ log_info! 'Post Authentication', 'Identification', 'User', "#{user[:info]['nickname']}"
964
+
965
+ # jadams, 2019-07-22: Check if it's needed to modify the respose header
966
+ #
967
+ # log_info! 'API', 'Auth Request', 'Set Last-Modified', "#{time}"
968
+ # response.headers['Last-Modified'] = time
969
+ # response.headers['Cache-Control'] = 'private,max-age=0,must-revalidate,no-store'
970
+ # response.headers['X-J1-AuthManager'] = "page-validated;category=#{category};called=" + time
971
+
972
+ log_info! 'Post Authentication', 'Redirect', 'Pass to requested page', "#{user_state_data['requested_page']}"
973
+ redirect user_state_data['requested_page']
974
+
975
+ end
976
+ # END: get /post_authentication
977
+ # --------------------------------------------------------------------------
978
+
979
+ # ENDPOINT status (called from WEB to get current state of an user)
980
+ # --------------------------------------------------------------------------
981
+ get '/status' do
982
+ requested_page = params.fetch('page')
983
+ category = 'public'
984
+
985
+ requested_page.scan(/(public|protected|private)/) do |match|
986
+ category = match[0]
987
+ end
988
+
989
+ log_info! 'API', 'Status Request', 'Info request received'
990
+ log_info! 'API', 'Status Request', 'Page requested', "#{requested_page}"
991
+ log_info! 'API', 'Status Request', 'Content type', "#{category}"
992
+
993
+ # if request.warden.user.respond_to?(:info)
994
+ #
995
+ if warden.authenticated?
996
+ user_name = warden.user[:info]['nickname']
997
+ user_id = warden.user[:uid]
998
+ users_allowed = providers[warden.user[:provider]]['users']
999
+ provider = warden.user[:provider]
1000
+ provider_permissions = user_state_data['provider_permissions']
1001
+ provider_site_url = warden.user[:info][:urls][:site]
1002
+ provider_home_url = warden.user[:info][:urls][:home]
1003
+ provider_blog_url = warden.user[:info][:urls][:blog]
1004
+ provider_member_url = warden.user[:info][:urls][:member]
1005
+
1006
+ if provider == 'patreon'
1007
+ provider_membership = warden.user[:extra][:reward][:name]
1008
+ provider_member_url = warden.user[:extra][:reward][:link]
1009
+ else
1010
+ provider_membership = 'member'
1011
+ provider_member_url = '#'
1012
+ end
1013
+
1014
+ log_info! 'API', 'Status Request', 'User detected', "#{user_name}"
1015
+ log_info! 'API', 'Status Request', 'User detected as signed in'
1016
+ else
1017
+ user_name = 'unknown'
1018
+ log_info! 'API', 'Status Request', 'User detected', 'signed out'
1019
+ end
1020
+
1021
+ # time = Time.now.ctime.to_s
1022
+ time = Time.now.strftime("%Y-%m-%d %H:%M:%S")
1023
+
1024
+ # if request.warden.authenticated?
1025
+ #
1026
+ if user_name != 'unknown'
1027
+ log_info! 'API', 'Status Request', 'Send data', 'SIGNED_IN'
1028
+ content_type 'application/json'
1029
+ {
1030
+ user_name: user_name,
1031
+ user_id: user_id,
1032
+ users_allowed: users_allowed,
1033
+ provider: provider,
1034
+ provider_membership: provider_membership,
1035
+ provider_permissions: provider_permissions,
1036
+ provider_site_url: provider_site_url,
1037
+ provider_home_url: provider_home_url,
1038
+ provider_blog_url: provider_blog_url,
1039
+ provider_member_url: provider_member_url,
1040
+ page_permission: category,
1041
+ requested_page: requested_page,
1042
+ authenticated: 'true',
1043
+ processed: time
1044
+ }.to_json
1045
+ else
1046
+ log_info! 'API', 'Status Request', 'Send data', 'SIGNED_OUT'
1047
+ content_type 'application/json'
1048
+ {
1049
+ user_name: 'visitor',
1050
+ user_id: 'unknown',
1051
+ users_allowed: 'all',
1052
+ provider: 'j1',
1053
+ provider_membership: 'guest',
1054
+ provider_permissions: 'public',
1055
+ provider_site_url: '#',
1056
+ provider_home_url: '#',
1057
+ provider_blog_url: '#',
1058
+ provider_member_url: '#',
1059
+ page_permission: category,
1060
+ requested_page: requested_page,
1061
+ authenticated: 'false',
1062
+ processed: time
1063
+ }.to_json
1064
+ end
1065
+ end
1066
+ # END: get /status
1067
+ # --------------------------------------------------------------------------
1068
+
1069
+ # ENDPOINT cookie_consent (exception, called from the app|auth manager)
1070
+ # --------------------------------------------------------------------------
1071
+ get '/cookie_consent' do
1072
+ provider = params.fetch('provider')
1073
+ category = params.fetch('category')
1074
+ user = params.fetch('user')
1075
+ requested_page = params.fetch('requested_page')
1076
+ description_title = params.fetch('title')
1077
+
1078
+ log_info! 'API', 'ExceptionHandler', 'Request received'
1079
+ log_info! 'ExceptionHandler', 'ERROR', 'Cookies declined'
1080
+ log_info! 'ExceptionHandler', 'Redirect', 'Pass to dialog page', 'Cookie Consent'
1081
+
1082
+ # Capitalize first char
1083
+ provider = provider.sub(/^./, &:upcase)
1084
+ route = requested_page
1085
+
1086
+ @route = route
1087
+ @provider = provider
1088
+ @modal = "centralCookieConsent"
1089
+ @info_type = "danger"
1090
+ @modal_icon = "cookie"
1091
+ @modal_agreed_text = "Yes, please"
1092
+ @modal_disagreed_text = "No, thanks"
1093
+ @modal_title = "Authentication Manager"
1094
+ # @modal_description = "<h4>#{description_title}</h4><br /><br />User <b>#{user}</b> from provider <b>#{provider}</b> requested access on <b>#{category}</b> pages.<br /> In order to continue, you need to accept on <b>Cookies</b>."
1095
+ @modal_description = "<h4>#{description_title}</h4><br /><br /> In order to continue, you need to accept on <b>Cookies</b>."
1096
+
1097
+ erb :auth_manager_ui
1098
+ end
1099
+ # END: get /cookies_rejected
1100
+ # --------------------------------------------------------------------------
1101
+
1102
+
1103
+ # ENDPOINT access_denied (exception, called from the app|auth manager)
1104
+ # --------------------------------------------------------------------------
1105
+ get '/access_denied' do
1106
+ provider = params.fetch('provider')
1107
+ category = params.fetch('category')
1108
+ user = params.fetch('user')
1109
+ description_title = params.fetch('title')
1110
+
1111
+ log_info! 'API', 'ExceptionHandler', 'Request received'
1112
+ log_info! 'ExceptionHandler', 'ERROR', 'Access Denied'
1113
+
1114
+ session_encoded = request.cookies['j1.user.state']
1115
+ session_decoded = Base64.decode64(session_encoded)
1116
+ user_state_data = JSON.parse(session_decoded)
1117
+
1118
+ # Update J1 web session data
1119
+ # --------------------------------------------------------------------
1120
+ # user_state_data['user_name'] = user
1121
+ # user_state_data['user_id'] = 'unknown'
1122
+ # user_state_data['users_allowed'] = 'unknown'
1123
+ # user_state_data['payment_status'] = 'unknown'
1124
+ # user_state_data['provider'] = provider
1125
+ # user_state_data['provider_url'] = 'unknown'
1126
+ # user_state_data['provider_permissions'] = 'unknown'
1127
+ # user_state_data['authenticated'] = 'false'
1128
+ # user_state_data['writer'] = 'middleware'
1129
+
1130
+ #log_info! 'ExceptionHandler', 'Cookie', 'Write web session data', "#{session_json}"
1131
+
1132
+ # write updated J1 session data to cookie
1133
+ #
1134
+ # session_json = user_state_data.to_json
1135
+ # session_encoded = Base64.encode64(session_json)
1136
+ # response.set_cookie(
1137
+ # 'j1.user.state',
1138
+ # domain: false,
1139
+ # value: session_encoded.to_s,
1140
+ # path: '/'
1141
+ # )
1142
+
1143
+ log_info! 'ExceptionHandler', 'Redirect', 'Pass to error page', "Access Denied"
1144
+
1145
+ # Capitalize first char
1146
+ provider = provider.sub(/^./, &:upcase)
1147
+ route = '/'
1148
+
1149
+ @route = route
1150
+ @provider = provider
1151
+ @modal = "centralModalInfo"
1152
+ @info_type = "danger"
1153
+ @modal_icon = "account-off"
1154
+ @modal_ok_text = "Ok, understood"
1155
+ @modal_title = "Authentication Manager"
1156
+ @modal_description = "<h4>#{description_title}</h4></br></br> User <b>#{user}</b> from provider <b>#{provider}</b> is not allowed to access <b>#{category}</b> pages."
1157
+
1158
+ erb :auth_manager_ui
1159
+ end
1160
+ # END: get '/access_denied'
1161
+ # --------------------------------------------------------------------------
1162
+
1163
+
1164
+ # ENDPOINT invalid_funds (exception, called from the app|auth manager)
1165
+ # --------------------------------------------------------------------------
1166
+ get '/invalid_funds' do
1167
+ provider = params.fetch('provider')
1168
+ category = params.fetch('category')
1169
+ user = params.fetch('user')
1170
+ description_title = params.fetch('title')
1171
+
1172
+ log_info! 'API', 'ExceptionHandler', 'Request received'
1173
+ log_info! 'ExceptionHandler', 'ERROR', 'Invalid Funds'
1174
+
1175
+ session_encoded = request.cookies['j1.user.state']
1176
+ session_decoded = Base64.decode64(session_encoded)
1177
+ user_state_data = JSON.parse(session_decoded)
1178
+
1179
+ # Update J1 web session data
1180
+ # --------------------------------------------------------------------
1181
+ # user_state_data['user_name'] = user
1182
+ # user_state_data['user_id'] = 'unknown'
1183
+ # user_state_data['users_allowed'] = 'unknown'
1184
+ # user_state_data['payment_status'] = 'unknown'
1185
+ # user_state_data['provider'] = provider
1186
+ # user_state_data['provider_url'] = 'unknown'
1187
+ # user_state_data['provider_permissions'] = 'unknown'
1188
+ # user_state_data['authenticated'] = 'false'
1189
+ # user_state_data['writer'] = 'middleware'
1190
+
1191
+ #log_info! 'ExceptionHandler', 'Cookie', 'Write web session data', "#{session_json}"
1192
+
1193
+ # write updated J1 session data to cookie
1194
+ #
1195
+ log_info! 'API', 'Exception Handler', 'ERROR', 'Invalid Funds'
1196
+
1197
+ # session_json = user_state_data.to_json
1198
+ # session_encoded = Base64.encode64(session_json)
1199
+ # response.set_cookie(
1200
+ # 'j1.user.state',
1201
+ # domain: false,
1202
+ # value: session_encoded.to_s,
1203
+ # path: '/'
1204
+ # )
1205
+
1206
+ log_info! 'ExceptionHandler', 'Redirect', 'Pass to error page', 'Invalid Funds'
1207
+
1208
+ # Capitalize first char
1209
+ provider = provider.sub(/^./, &:upcase)
1210
+ route = '/'
1211
+
1212
+ @route = route
1213
+ @provider = provider
1214
+ @modal = "centralModalInfo"
1215
+ @info_type = "danger"
1216
+ @modal_icon = "account-off"
1217
+ @modal_ok_text = "Ok, understood"
1218
+ @modal_title = "Authentication Manager"
1219
+ @modal_description = "<h4>#{description_title}</h4></br></br> User <b>#{user}</b> from provider <b>#{provider}</b> is not allowed to access <b>#{category}</b> pages."
1220
+
1221
+ erb :auth_manager_ui
1222
+ end
1223
+ # END: get /invalid_funds
1224
+ # --------------------------------------------------------------------------
1225
+
1226
+
1227
+ # access_protected_content ENDPOINT called from the app (auth manager)
1228
+ # --------------------------------------------------------------------------
1229
+ get '/page_validation' do
1230
+ provider = params.fetch('provider')
1231
+ allowed_users = params.fetch('allowed_users')
1232
+ page = params.fetch('page')
1233
+ category = params.fetch('category')
1234
+
1235
+ log_info! 'API', 'PageAccessControl', 'PageValidate request received'
1236
+
1237
+ # Capitalize first char
1238
+ # provider = provider.sub(/^./, &:upcase)
1239
+
1240
+ log_info! 'PageAccessControl', 'AuthCheck', 'Check provider', "#{provider}"
1241
+ # jadams, 2019-03-16: Hier ist das Problem
1242
+ #
1243
+ if warden.authenticated?
1244
+ log_info! 'PageAccessControl', 'AuthCheck', 'Grant access for', "#{provider}"
1245
+ log_info! 'PageAccessControl', 'Redirect', 'Pass to page', "#{page}"
1246
+ route = page
1247
+ else
1248
+ log_info! 'PageAccessControl', 'AuthCheck', 'Authentication failed', "#{provider}"
1249
+ route = "/authentication?request=signin&provider=#{provider}&allowed_users=#{allowed_users}"
1250
+ end
1251
+
1252
+ log_info! 'PageAccessControl', 'Redirect', 'Pass to SignIn dialog, page', "#{page}"
1253
+ # Capitalize first char
1254
+ provider = provider.sub(/^./, &:upcase)
1255
+
1256
+ @provider = provider
1257
+ @route = route
1258
+ @modal = "signInProtectedContent"
1259
+ @modal_icon = "login"
1260
+ @modal_agreed_text = "Yes, please"
1261
+ @modal_disagreed_text = "No, thanks"
1262
+ @modal_title = "SignIn"
1263
+ @modal_image = "/assets/images/master_header/admin-dashboard-bootstrap-1280x600.png"
1264
+ @modal_description = "The page <b>#{page}</b> you requested belongs to <b>#{category}</b> content. You'll be redirected to authenticate with the provider <b>#{provider}</b>. If signed in successfully, you get access to all <b>#{category} pages</b>."
1265
+
1266
+ erb :auth_manager_ui
1267
+ end
1268
+ # END: get '/page_validation
1269
+ # --------------------------------------------------------------------------
1270
+
1271
+ # ENDPOINT iframe
1272
+ # --------------------------------------------------------------------------
1273
+ get '/iframe' do
1274
+ @website_url = "https://jekyll-one.github.io/"
1275
+ erb :iframe
1276
+ end
1277
+ # END: get /iframe
1278
+ # --------------------------------------------------------------------------
1279
+
1280
+ # Rescue OmniAuth::Strategies::OAuth2::CallbackError
1281
+ # ------------------------------------------------------------------------
1282
+ get '/redirect_on_failure' do
1283
+ log_error! 'OmniAuth', 'OAuth2 ', 'Callback error on redirect'
1284
+ log_info! 'Redirect on failure', 'Redirect', 'Pass to home page'
1285
+ redirect "/" # user_state_data['requested_page']
1286
+ end
1287
+ # END: get /redirect_on_failure
1288
+ # --------------------------------------------------------------------------
1289
+
1290
+ # ENDPOINT page_authentication
1291
+ # --------------------------------------------------------------------------
1292
+ get '/page_authentication' do
1293
+ requested_page = params.fetch('page')
1294
+
1295
+ reward = {
1296
+ :id => 'unknown',
1297
+ :name => 'unknown',
1298
+ :link => '#'
1299
+ }
1300
+ campaign = {
1301
+ :id => 'unknown',
1302
+ :link => '#'
1303
+ }
1304
+
1305
+ log_info! 'API', 'Auth Request', 'Request received for', "#{requested_page}"
1306
+
1307
+ log_info! 'API', 'Auth Request', 'Read user state data from cookie'
1308
+ session_encoded = request.cookies['j1.user.state']
1309
+ session_decoded = Base64.decode64(session_encoded)
1310
+ user_state_data = JSON.parse(session_decoded)
1311
+
1312
+ user = warden.user
1313
+ user_json = user.to_json
1314
+
1315
+ if user[:provider] === 'disqus'
1316
+ user[:info][:urls][:site] = "https://disqus.com"
1317
+ user[:info][:urls][:home] = user[:info]['urls']['profileUrl']
1318
+ user[:info][:urls][:blog] = "https://disqus.com/by/juergen_adams/"
1319
+ user[:info][:urls][:member] = user[:info]['urls']['profileUrl']
1320
+ end
1321
+
1322
+ if user[:provider] === 'github'
1323
+ user[:info][:urls][:site] = "https://github.com"
1324
+ user[:info][:urls][:home] = user[:info]['urls']['GitHub']
1325
+ user[:info][:urls][:blog] = "https://github.com/jekyll-one"
1326
+ user[:info][:urls][:member] = user[:info]['urls']['Blog']
1327
+ end
1328
+
1329
+ if user[:provider] === 'patreon'
1330
+
1331
+ user[:info][:urls][:site] = "https://patreon.com"
1332
+ user[:info][:urls][:home] = "https://patreon.com/home"
1333
+ user[:info][:urls][:blog] = "https://patreon.com/jekyll_one"
1334
+
1335
+ unless user[:info]['payment_info'].empty?
1336
+ reward_url = user[:info]['payment_info']['relationships']['reward']['links']['related']
1337
+ reward_json = RestClient.get "#{reward_url}", {:content_type => :json, :accept => :json}
1338
+ reward_data = JSON.parse(reward_json)
1339
+ user[:info][:urls][:member] = "https://patreon.com" + reward_data['data']['attributes']['url']
1340
+ user[:info][:payment_status] = user[:info]['payment_info']['attributes']['declined_since'].nil? ? 'true' : 'false'
1341
+ else
1342
+ reward_url = ""
1343
+ reward_json = ""
1344
+ reward_data = ""
1345
+ user[:info][:payment_status] = 'false'
1346
+ end
1347
+
1348
+ unless reward_data.empty?
1349
+ reward[:id] = reward_data['data']['id']
1350
+ reward[:name] = reward_data['data']['attributes']['title']
1351
+ reward[:link] = "https://patreon.com" + reward_data['data']['attributes']['url']
1352
+ campaign[:id] = reward_data['data']['relationships']['campaign']['data']['id']
1353
+ campaign[:link] = reward_data['data']['relationships']['campaign']['links']['related']
1354
+ else
1355
+ reward[:id] = ""
1356
+ reward[:name] = "no tiers"
1357
+ reward[:link] = ""
1358
+ campaign[:id] = ""
1359
+ campaign[:link] = ""
1360
+ end
1361
+ end
1362
+
1363
+ user[:extra][:reward] = reward
1364
+ user[:extra][:campaign] = campaign
1365
+
1366
+ if user.nil?
1367
+ # Collection of session data failed (e.g cookie > 4K)
1368
+ #
1369
+ log_info! 'API', 'Auth Request', 'Internal error', 'User identification failed'
1370
+ warden.logout
1371
+ session.clear
1372
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
1373
+ description_title = "Access Denied"
1374
+ redirect "/access_denied?provider=unknown&user=unknown&category=unknown&title=#{description_title}"
1375
+ else
1376
+ log_info! 'API', 'Auth Request', 'User identified successfully'
1377
+ user_state_data['user_name'] = user[:info]['nickname']
1378
+ user_state_data['user_id'] = user[:uid]
1379
+ user_state_data['provider'] = user[:provider]
1380
+ user_state_data['provider_membership'] = 'member'
1381
+ user_state_data['provider_permissions'] = providers["#{user[:provider]}"]['permissions']
1382
+ user_state_data['users_allowed'] = providers["#{user[:provider]}"]['users']
1383
+ user_state_data['authenticated'] = 'true'
1384
+ user_state_data['payment_status'] = user[:info][:payment_status]
1385
+ user_state_data['writer'] = 'middleware'
1386
+
1387
+ current_user = user[:info]['nickname'] = user[:info]['nickname']
1388
+ current_provider = user[:provider]
1389
+
1390
+ requested_page.scan(/(protected|private)/) do |match|
1391
+
1392
+ # Set category from requested page
1393
+ #
1394
+ category = match[0]
1395
+ log_info! 'API', 'Auth Request', 'Process content type', "#{category}"
1396
+
1397
+ # Check if user is allowed to access protected content in GENERAL
1398
+ #
1399
+ log_info! 'API', 'Auth Request', 'Check for allowed users'
1400
+ unless user_state_data['users_allowed'].include? 'all'
1401
+ unless user_state_data['users_allowed'].include? "#{current_user}"
1402
+ log_info! 'API', 'Auth Request', 'User not allowed', "#{current_user}"
1403
+ log_info! 'API', 'Auth Request', 'Allowed users', "#{user_state_data['users_allowed']}"
1404
+ log_info! 'API', 'Auth Request', 'Logout user from current session', "#{current_user}"
1405
+ warden.logout
1406
+ session.clear
1407
+ log_info! 'API', 'Auth Request', 'Pass to error page (access_denied)'
1408
+ description_title = "Access Denied"
1409
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
1410
+ end
1411
+ end
1412
+ log_info! 'API', 'Auth Request', 'Allowed users', "#{user_state_data['users_allowed']}"
1413
+
1414
+ # Check conditions to access protected content (if any)
1415
+ #
1416
+ log_info! 'API', 'Auth Request', 'Check for conditions', "#{current_provider}"
1417
+ check_conditions = providers["#{user[:provider]}"]['conditions'][category]['enabled']
1418
+ if check_conditions
1419
+
1420
+ if providers["#{user[:provider]}"]['conditions'][category]['users']['whitelist'].nil?
1421
+ category_whitelist = 'all'
1422
+ else
1423
+ category_whitelist = providers["#{user[:provider]}"]['conditions'][category]['users']['whitelist']
1424
+ end
1425
+
1426
+ # Check if user is BLACKLISTED
1427
+ #
1428
+ blacklist = providers["#{user[:provider]}"]['conditions'][category]['users']['blacklist']
1429
+ if blacklist.include? "#{current_user}"
1430
+ log_info! 'API', 'Auth Request', 'Check blacklisting'
1431
+ log_info! 'API', 'Auth Request', 'User blacklisted', "#{current_user}"
1432
+ user[:info][:blacklisted] = 'true'
1433
+ log_info! 'API', 'Auth Request', 'Logout user from current session', "#{current_user}"
1434
+ warden.logout
1435
+ session.clear
1436
+ log_info! 'API', 'Auth Request', 'Pass to error page (access_denied)'
1437
+ description_title = "Access Denied"
1438
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
1439
+ end
1440
+
1441
+ log_info! 'API', 'Auth Request', 'Check whitelisting'
1442
+ if category_whitelisted? category_whitelist, current_user
1443
+ user[:info][:whitelisted] = 'true'
1444
+ reward[:name] = 'whitelisted'
1445
+ log_info! 'API', 'Auth Request', 'User whitelisted', "#{current_user}"
1446
+ log_info! 'API', 'Auth Request', 'Reward set to', 'Whitelisted'
1447
+ else
1448
+ log_info! 'API', 'Auth Request', 'No whitelisting found', "#{current_user}"
1449
+ end
1450
+
1451
+ log_info! 'API', 'Auth Request', 'Check conditions'
1452
+ unless category_whitelisted? category_whitelist, current_user
1453
+ log_info! 'API', 'Auth Request', 'Check rewards'
1454
+ payment_tiers = providers["#{user[:provider]}"]['conditions'][category]['payment']['activated']
1455
+ log_info! 'API', 'Auth Request', 'Check rewards', "#{current_user}"
1456
+ if payment_activated? payment_tiers
1457
+ log_info! 'API', 'Auth Request', 'Reward found', "#{reward[:name]}"
1458
+
1459
+ # Check if any payment exists for that user
1460
+ #
1461
+ log_info! 'API', 'Auth Request', 'Check payment status'
1462
+ if user[:info]['payment_info'].empty?
1463
+ log_info! 'API', 'Auth Request', 'Payment status: NOT AVAILABLE', "#{current_user}"
1464
+ log_info! 'API', 'Auth Request', 'Logout user from current session', "#{current_user}"
1465
+ warden.logout
1466
+ session.clear
1467
+ log_info! 'API', 'Auth Request', 'Pass to error page (access_denied)'
1468
+ description_title = "Access Denied"
1469
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
1470
+ end
1471
+
1472
+ # Check for VALID payments (scope: pledge-to-me)
1473
+ #
1474
+ payment_status = user[:info]['payment_info']['attributes']['declined_since']
1475
+ unless payment_valid? payment_status
1476
+ log_info! 'API', 'Auth Request', 'Payment status INVALID', "#{current_user}"
1477
+ log_info! 'API', 'Auth Request', 'Logout user from current session', "#{current_user}"
1478
+ warden.logout
1479
+ session.clear
1480
+ log_info! 'API', 'Auth Request', 'Pass to error page (access_denied)'
1481
+ description_title = "Access Denied"
1482
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
1483
+ else
1484
+ log_info! 'API', 'Auth Request', 'Payment status VALID', "#{current_user}"
1485
+ end
1486
+ end
1487
+
1488
+ end
1489
+ # end category_whitelisted
1490
+ else
1491
+ category_condition_state = providers["#{user[:provider]}"]['conditions'][category]['enabled']
1492
+ log_info! 'API', 'Auth Request', 'Category check failed for', "#{current_provider}"
1493
+ log_info! 'API', 'Auth Request', "Category checked", "#{category}"
1494
+ log_info! 'API', 'Auth Request', "Category support", "#{category_condition_state}"
1495
+ warden.logout
1496
+ session.clear
1497
+ log_info! 'API', 'Auth Request', 'Pass to error page (access_denied)'
1498
+ description_title = "Access Denied"
1499
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
1500
+ end
1501
+ # end check conditions
1502
+
1503
+ end
1504
+ # end protected content
1505
+ end
1506
+ # end user.nil?
1507
+
1508
+
1509
+ # user_state_data['provider'] = current_provider
1510
+ # user_state_data['users_allowed'] = providers["#{current_provider}"]['users']
1511
+
1512
+ # TODO: Add membership|product specific data for the SideBar
1513
+
1514
+ # write updated J1 session data to cookie
1515
+ #
1516
+ # session_json = user_state_data.to_json
1517
+ # log_info! 'Post Authentication', 'Cookie', 'Write web session data', "#{session_json}"
1518
+ # session_encoded = Base64.encode64(session_json)
1519
+ # response.set_cookie(
1520
+ # 'j1.user.state',
1521
+ # domain: false,
1522
+ # value: session_encoded.to_s,
1523
+ # path: '/'
1524
+ # )
1525
+
1526
+ # redirect authenticated|validated user to requested page
1527
+ #
1528
+ time = Time.now.ctime.to_s
1529
+
1530
+ log_info! 'API', 'Auth Request', 'Provider', "#{user[:provider]}"
1531
+ log_info! 'API', 'Auth Request', 'User', "#{user[:info]['nickname']}"
1532
+
1533
+ # jadams, 2019-07-22: Check if it's needed to modify the respose header
1534
+ #
1535
+ # log_info! 'API', 'Auth Request', 'Set Last-Modified', "#{time}"
1536
+ # response.headers['Last-Modified'] = time
1537
+ # response.headers['Cache-Control'] = 'private,max-age=0,must-revalidate,no-store'
1538
+ # response.headers['X-J1-AuthManager'] = "page-validated;category=#{category};called=" + time
1539
+
1540
+ log_info! 'API', 'Auth Request', 'Pass to requested page', "#{requested_page}"
1541
+ redirect requested_page
1542
+
1543
+ end
1544
+ # END: get /page_authentication
1545
+ # --------------------------------------------------------------------------
1546
+
1547
+ end
1548
+ end