platform 3.1.1

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 (480) hide show
  1. data/.gitignore +21 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +14 -0
  4. data/Gemfile.lock +191 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.rdoc +5 -0
  7. data/Rakefile +37 -0
  8. data/app/assets/images/platform/.gitkeep +0 -0
  9. data/app/assets/images/platform/accept.png +0 -0
  10. data/app/assets/images/platform/action_tab_bkgd.gif +0 -0
  11. data/app/assets/images/platform/action_tab_white_bkgd.gif +0 -0
  12. data/app/assets/images/platform/add.png +0 -0
  13. data/app/assets/images/platform/apps/app_icon.gif +0 -0
  14. data/app/assets/images/platform/apps/app_logo.gif +0 -0
  15. data/app/assets/images/platform/arrow_down.gif +0 -0
  16. data/app/assets/images/platform/arrow_down.png +0 -0
  17. data/app/assets/images/platform/arrow_down_grey.png +0 -0
  18. data/app/assets/images/platform/arrow_right.gif +0 -0
  19. data/app/assets/images/platform/arrow_up.png +0 -0
  20. data/app/assets/images/platform/arrow_up_grey.png +0 -0
  21. data/app/assets/images/platform/bullet_go.png +0 -0
  22. data/app/assets/images/platform/buttons.png +0 -0
  23. data/app/assets/images/platform/cancel.png +0 -0
  24. data/app/assets/images/platform/clipboard_icon.gif +0 -0
  25. data/app/assets/images/platform/close.gif +0 -0
  26. data/app/assets/images/platform/cross.png +0 -0
  27. data/app/assets/images/platform/default_app_icon.gif +0 -0
  28. data/app/assets/images/platform/default_app_logo.gif +0 -0
  29. data/app/assets/images/platform/delete.png +0 -0
  30. data/app/assets/images/platform/disk.png +0 -0
  31. data/app/assets/images/platform/exclamation.png +0 -0
  32. data/app/assets/images/platform/eye.png +0 -0
  33. data/app/assets/images/platform/eye_not.png +0 -0
  34. data/app/assets/images/platform/field_sprite.gif +0 -0
  35. data/app/assets/images/platform/find.png +0 -0
  36. data/app/assets/images/platform/globe.gif +0 -0
  37. data/app/assets/images/platform/help.png +0 -0
  38. data/app/assets/images/platform/help/app_reg.png +0 -0
  39. data/app/assets/images/platform/help/app_reg_ext.png +0 -0
  40. data/app/assets/images/platform/help/app_reg_web.png +0 -0
  41. data/app/assets/images/platform/help/auth_desktop.png +0 -0
  42. data/app/assets/images/platform/help/auth_iframe.png +0 -0
  43. data/app/assets/images/platform/help/auth_iphone.png +0 -0
  44. data/app/assets/images/platform/help/auth_web.png +0 -0
  45. data/app/assets/images/platform/help/authorize.png +0 -0
  46. data/app/assets/images/platform/help/ext.png +0 -0
  47. data/app/assets/images/platform/help/login.png +0 -0
  48. data/app/assets/images/platform/help/login_desktop.png +0 -0
  49. data/app/assets/images/platform/help/login_iphone.png +0 -0
  50. data/app/assets/images/platform/help/login_web.png +0 -0
  51. data/app/assets/images/platform/help2.png +0 -0
  52. data/app/assets/images/platform/information.png +0 -0
  53. data/app/assets/images/platform/keyboard.png +0 -0
  54. data/app/assets/images/platform/language_selector_arrow.gif +0 -0
  55. data/app/assets/images/platform/left_quote.png +0 -0
  56. data/app/assets/images/platform/lightning.png +0 -0
  57. data/app/assets/images/platform/loading.gif +0 -0
  58. data/app/assets/images/platform/loading2.gif +0 -0
  59. data/app/assets/images/platform/loading3.gif +0 -0
  60. data/app/assets/images/platform/loading_animation.gif +0 -0
  61. data/app/assets/images/platform/loading_large.gif +0 -0
  62. data/app/assets/images/platform/lock.png +0 -0
  63. data/app/assets/images/platform/lock_add.png +0 -0
  64. data/app/assets/images/platform/lock_delete.png +0 -0
  65. data/app/assets/images/platform/lock_open.png +0 -0
  66. data/app/assets/images/platform/medals/bronze.png +0 -0
  67. data/app/assets/images/platform/medals/gold.png +0 -0
  68. data/app/assets/images/platform/medals/runner.png +0 -0
  69. data/app/assets/images/platform/medals/silver.png +0 -0
  70. data/app/assets/images/platform/minus_node.png +0 -0
  71. data/app/assets/images/platform/oauth/perm_tile.gif +0 -0
  72. data/app/assets/images/platform/oauth/right_grey.png +0 -0
  73. data/app/assets/images/platform/pencil.png +0 -0
  74. data/app/assets/images/platform/photo_silhouette.gif +0 -0
  75. data/app/assets/images/platform/pixel.gif +0 -0
  76. data/app/assets/images/platform/platform.png +0 -0
  77. data/app/assets/images/platform/platform2.png +0 -0
  78. data/app/assets/images/platform/platform3.png +0 -0
  79. data/app/assets/images/platform/platform4.png +0 -0
  80. data/app/assets/images/platform/platform5.png +0 -0
  81. data/app/assets/images/platform/plus.png +0 -0
  82. data/app/assets/images/platform/plus_node.png +0 -0
  83. data/app/assets/images/platform/random.png +0 -0
  84. data/app/assets/images/platform/random2.png +0 -0
  85. data/app/assets/images/platform/rating_star0.png +0 -0
  86. data/app/assets/images/platform/rating_star05.png +0 -0
  87. data/app/assets/images/platform/rating_star1.png +0 -0
  88. data/app/assets/images/platform/rating_stars.gif +0 -0
  89. data/app/assets/images/platform/rating_stars.psd +0 -0
  90. data/app/assets/images/platform/reply.png +0 -0
  91. data/app/assets/images/platform/right_quote.png +0 -0
  92. data/app/assets/images/platform/rotating_world.gif +0 -0
  93. data/app/assets/images/platform/script.png +0 -0
  94. data/app/assets/images/platform/script_edit.png +0 -0
  95. data/app/assets/images/platform/script_gear.png +0 -0
  96. data/app/assets/images/platform/site_sprite.gif +0 -0
  97. data/app/assets/images/platform/spinner.gif +0 -0
  98. data/app/assets/images/platform/star.png +0 -0
  99. data/app/assets/images/platform/table_edit.png +0 -0
  100. data/app/assets/images/platform/table_gear.png +0 -0
  101. data/app/assets/images/platform/table_multiple.png +0 -0
  102. data/app/assets/images/platform/thumb_down.png +0 -0
  103. data/app/assets/images/platform/thumb_up.png +0 -0
  104. data/app/assets/images/platform/top_left_stem.png +0 -0
  105. data/app/assets/images/platform/top_right_stem.png +0 -0
  106. data/app/assets/images/platform/translate_icn.gif +0 -0
  107. data/app/assets/images/platform/treeview/diffDoc.gif +0 -0
  108. data/app/assets/images/platform/treeview/diffFolder.gif +0 -0
  109. data/app/assets/images/platform/treeview/ftv2blank.gif +0 -0
  110. data/app/assets/images/platform/treeview/ftv2doc.gif +0 -0
  111. data/app/assets/images/platform/treeview/ftv2folderclosed.gif +0 -0
  112. data/app/assets/images/platform/treeview/ftv2folderopen.gif +0 -0
  113. data/app/assets/images/platform/treeview/ftv2lastnode.gif +0 -0
  114. data/app/assets/images/platform/treeview/ftv2link.gif +0 -0
  115. data/app/assets/images/platform/treeview/ftv2mlastnode.gif +0 -0
  116. data/app/assets/images/platform/treeview/ftv2mnode.gif +0 -0
  117. data/app/assets/images/platform/treeview/ftv2node.gif +0 -0
  118. data/app/assets/images/platform/treeview/ftv2plastnode.gif +0 -0
  119. data/app/assets/images/platform/treeview/ftv2pnode.gif +0 -0
  120. data/app/assets/images/platform/treeview/ftv2vertline.gif +0 -0
  121. data/app/assets/images/platform/wizard.png +0 -0
  122. data/app/assets/images/platform/world_link.png +0 -0
  123. data/app/assets/javascripts/platform/api_explorer.js +628 -0
  124. data/app/assets/javascripts/platform/application.js +9 -0
  125. data/app/assets/javascripts/platform/ftiens4.js +1197 -0
  126. data/app/assets/javascripts/platform/jsdk.js +539 -0
  127. data/app/assets/javascripts/platform/platform.js +447 -0
  128. data/app/assets/javascripts/platform/shortcut.js +223 -0
  129. data/app/assets/javascripts/platform/ua.js +147 -0
  130. data/app/assets/stylesheets/platform/api_explorer.css.scss +140 -0
  131. data/app/assets/stylesheets/platform/application.css.scss +6 -0
  132. data/app/assets/stylesheets/platform/components.css.scss +208 -0
  133. data/app/assets/stylesheets/platform/layout.css.scss +119 -0
  134. data/app/assets/stylesheets/platform/oauth.css +51 -0
  135. data/app/assets/stylesheets/platform/platform.css.scss +311 -0
  136. data/app/controllers/platform/admin/apps_controller.rb +99 -0
  137. data/app/controllers/platform/admin/base_controller.rb +60 -0
  138. data/app/controllers/platform/admin/categories_controller.rb +132 -0
  139. data/app/controllers/platform/admin/clientsdk_controller.rb +30 -0
  140. data/app/controllers/platform/admin/developers_controller.rb +30 -0
  141. data/app/controllers/platform/admin/exceptions_controller.rb +30 -0
  142. data/app/controllers/platform/admin/forum_controller.rb +34 -0
  143. data/app/controllers/platform/admin/metrics_controller.rb +42 -0
  144. data/app/controllers/platform/api/apps_controller.rb +40 -0
  145. data/app/controllers/platform/api/base_controller.rb +541 -0
  146. data/app/controllers/platform/apps_controller.rb +142 -0
  147. data/app/controllers/platform/base_controller.rb +127 -0
  148. data/app/controllers/platform/developer/api_explorer_controller.rb +56 -0
  149. data/app/controllers/platform/developer/apps_controller.rb +161 -0
  150. data/app/controllers/platform/developer/base_controller.rb +51 -0
  151. data/app/controllers/platform/developer/blog_controller.rb +29 -0
  152. data/app/controllers/platform/developer/dashboard_controller.rb +63 -0
  153. data/app/controllers/platform/developer/forum_controller.rb +85 -0
  154. data/app/controllers/platform/developer/help_controller.rb +113 -0
  155. data/app/controllers/platform/developer/info_controller.rb +41 -0
  156. data/app/controllers/platform/developer/registration_controller.rb +39 -0
  157. data/app/controllers/platform/developer/resources_controller.rb +30 -0
  158. data/app/controllers/platform/forum_controller.rb +74 -0
  159. data/app/controllers/platform/oauth_controller.rb +421 -0
  160. data/app/controllers/platform/ratings_controller.rb +61 -0
  161. data/app/helpers/platform/admin/categories_helper.rb +54 -0
  162. data/app/helpers/platform/apps_helper.rb +26 -0
  163. data/app/helpers/platform/developer/dashboard_helper.rb +42 -0
  164. data/app/helpers/platform/developer/help_helper.rb +45 -0
  165. data/app/helpers/platform_helper.rb +26 -0
  166. data/app/models/platform/application.rb +394 -0
  167. data/app/models/platform/application_category.rb +34 -0
  168. data/app/models/platform/application_developer.rb +30 -0
  169. data/app/models/platform/application_filter.rb +30 -0
  170. data/app/models/platform/application_log.rb +32 -0
  171. data/app/models/platform/application_log_filter.rb +34 -0
  172. data/app/models/platform/application_metric.rb +58 -0
  173. data/app/models/platform/application_metric_filter.rb +34 -0
  174. data/app/models/platform/application_permission.rb +30 -0
  175. data/app/models/platform/application_permission_filter.rb +30 -0
  176. data/app/models/platform/application_usage_metric.rb +58 -0
  177. data/app/models/platform/application_usage_metric_filter.rb +34 -0
  178. data/app/models/platform/application_user.rb +45 -0
  179. data/app/models/platform/application_user_filter.rb +34 -0
  180. data/app/models/platform/base_filter.rb +46 -0
  181. data/app/models/platform/category.rb +64 -0
  182. data/app/models/platform/daily_application_metric.rb +31 -0
  183. data/app/models/platform/developer.rb +45 -0
  184. data/app/models/platform/developer_filter.rb +26 -0
  185. data/app/models/platform/forum_message.rb +35 -0
  186. data/app/models/platform/forum_message_filter.rb +26 -0
  187. data/app/models/platform/forum_topic.rb +38 -0
  188. data/app/models/platform/forum_topic_filter.rb +26 -0
  189. data/app/models/platform/logged_exception.rb +290 -0
  190. data/app/models/platform/logged_exception_filter.rb +58 -0
  191. data/app/models/platform/media/image.rb +26 -0
  192. data/app/models/platform/media/media.rb +58 -0
  193. data/app/models/platform/monthly_application_metric.rb +31 -0
  194. data/app/models/platform/oauth/access_token.rb +57 -0
  195. data/app/models/platform/oauth/client_token.rb +38 -0
  196. data/app/models/platform/oauth/oauth_model_methods.rb +41 -0
  197. data/app/models/platform/oauth/oauth_token.rb +57 -0
  198. data/app/models/platform/oauth/oauth_token_filter.rb +34 -0
  199. data/app/models/platform/oauth/refresh_token.rb +47 -0
  200. data/app/models/platform/oauth/request_token.rb +50 -0
  201. data/app/models/platform/permission.rb +27 -0
  202. data/app/models/platform/rating.rb +43 -0
  203. data/app/models/platform/rating_filter.rb +30 -0
  204. data/app/models/platform/rollup_log.rb +27 -0
  205. data/app/models/platform/rollup_log_filter.rb +30 -0
  206. data/app/models/platform/total_application_metric.rb +40 -0
  207. data/app/models/platform/weekly_application_metric.rb +31 -0
  208. data/app/views/platform/admin/apps/_categories.html.erb +17 -0
  209. data/app/views/platform/admin/apps/_categories_scripts.html.erb +17 -0
  210. data/app/views/platform/admin/apps/_tabs.html.erb +25 -0
  211. data/app/views/platform/admin/apps/index.html.erb +32 -0
  212. data/app/views/platform/admin/apps/permissions.html.erb +7 -0
  213. data/app/views/platform/admin/apps/ratings.html.erb +7 -0
  214. data/app/views/platform/admin/apps/tokens.html.erb +18 -0
  215. data/app/views/platform/admin/apps/users.html.erb +7 -0
  216. data/app/views/platform/admin/apps/view.html.erb +170 -0
  217. data/app/views/platform/admin/categories/_tabs.html.erb +22 -0
  218. data/app/views/platform/admin/categories/category_assigner.html.erb +9 -0
  219. data/app/views/platform/admin/categories/category_assigner_tree.html.erb +81 -0
  220. data/app/views/platform/admin/categories/index.html.erb +106 -0
  221. data/app/views/platform/admin/categories/items.html.erb +153 -0
  222. data/app/views/platform/admin/categories/lb_update_application_category.html.erb +54 -0
  223. data/app/views/platform/admin/categories/lb_update_category.html.erb +64 -0
  224. data/app/views/platform/admin/categories/tree.html.erb +64 -0
  225. data/app/views/platform/admin/clientsdk/index.html.erb +89 -0
  226. data/app/views/platform/admin/common/_footer.html.erb +1 -0
  227. data/app/views/platform/admin/common/_header.html.erb +32 -0
  228. data/app/views/platform/admin/common/_lightbox_buttons.html.erb +5 -0
  229. data/app/views/platform/admin/common/_paginator.html.erb +20 -0
  230. data/app/views/platform/admin/developers/_tabs.html.erb +22 -0
  231. data/app/views/platform/admin/developers/index.html.erb +7 -0
  232. data/app/views/platform/admin/exceptions/_tabs.html.erb +22 -0
  233. data/app/views/platform/admin/exceptions/index.html.erb +7 -0
  234. data/app/views/platform/admin/forum/_tabs.html.erb +22 -0
  235. data/app/views/platform/admin/forum/index.html.erb +7 -0
  236. data/app/views/platform/admin/forum/messages.html.erb +7 -0
  237. data/app/views/platform/admin/metrics/_tabs.html.erb +25 -0
  238. data/app/views/platform/admin/metrics/application_log.html.erb +7 -0
  239. data/app/views/platform/admin/metrics/index.html.erb +9 -0
  240. data/app/views/platform/admin/metrics/rollup_log.html.erb +7 -0
  241. data/app/views/platform/admin/metrics/usage.html.erb +7 -0
  242. data/app/views/platform/apps/_actions_module.html.erb +3 -0
  243. data/app/views/platform/apps/_app_footer.html.erb +8 -0
  244. data/app/views/platform/apps/_app_header.html.erb +25 -0
  245. data/app/views/platform/apps/_apps_module.html.erb +42 -0
  246. data/app/views/platform/apps/_authorize_form.html.erb +11 -0
  247. data/app/views/platform/apps/_categories_module.html.erb +11 -0
  248. data/app/views/platform/apps/_featured_apps_module.html.erb +40 -0
  249. data/app/views/platform/apps/_left.html.erb +20 -0
  250. data/app/views/platform/apps/_monthly_users_module.html.erb +8 -0
  251. data/app/views/platform/apps/_paginator.html.erb +13 -0
  252. data/app/views/platform/apps/_rank_module.html.erb +18 -0
  253. data/app/views/platform/apps/_search_apps_module.html.erb +35 -0
  254. data/app/views/platform/apps/canvas_app.html.erb +15 -0
  255. data/app/views/platform/apps/index.html.erb +86 -0
  256. data/app/views/platform/apps/view.html.erb +71 -0
  257. data/app/views/platform/apps/xd.html.erb +11 -0
  258. data/app/views/platform/common/_footer.html.erb +1 -0
  259. data/app/views/platform/common/_header.html.erb +4 -0
  260. data/app/views/platform/common/_paginator.html.erb +32 -0
  261. data/app/views/platform/common/_scripts.html.erb +7 -0
  262. data/app/views/platform/common/_user_login.html.erb +11 -0
  263. data/app/views/platform/developer/api_explorer/history.html.erb +31 -0
  264. data/app/views/platform/developer/api_explorer/index.html.erb +134 -0
  265. data/app/views/platform/developer/api_explorer/oauth_lander.html.erb +4 -0
  266. data/app/views/platform/developer/api_explorer/options.html.erb +44 -0
  267. data/app/views/platform/developer/apps/_form.html.erb +340 -0
  268. data/app/views/platform/developer/apps/create_version.html.erb +19 -0
  269. data/app/views/platform/developer/apps/edit.html.erb +21 -0
  270. data/app/views/platform/developer/apps/index.html.erb +375 -0
  271. data/app/views/platform/developer/apps/new.html.erb +20 -0
  272. data/app/views/platform/developer/blog/index.html.erb +7 -0
  273. data/app/views/platform/developer/common/_footer.html.erb +1 -0
  274. data/app/views/platform/developer/common/_header.html.erb +34 -0
  275. data/app/views/platform/developer/dashboard/_apps_info.html.erb +84 -0
  276. data/app/views/platform/developer/dashboard/_discussions.html.erb +68 -0
  277. data/app/views/platform/developer/dashboard/_header.html.erb +12 -0
  278. data/app/views/platform/developer/dashboard/_reviews.html.erb +53 -0
  279. data/app/views/platform/developer/dashboard/_statistics.html.erb +105 -0
  280. data/app/views/platform/developer/dashboard/index.html.erb +85 -0
  281. data/app/views/platform/developer/dashboard/settings.html.erb +23 -0
  282. data/app/views/platform/developer/forum/_message.html.erb +17 -0
  283. data/app/views/platform/developer/forum/_messages.html.erb +14 -0
  284. data/app/views/platform/developer/forum/_new_message.html.erb +28 -0
  285. data/app/views/platform/developer/forum/_new_topic.html.erb +39 -0
  286. data/app/views/platform/developer/forum/index.html.erb +89 -0
  287. data/app/views/platform/developer/forum/topic.html.erb +28 -0
  288. data/app/views/platform/developer/help/_footer.html.erb +4 -0
  289. data/app/views/platform/developer/help/_header.html.erb +95 -0
  290. data/app/views/platform/developer/help/_navigation.html.erb +99 -0
  291. data/app/views/platform/developer/help/api.html.erb +120 -0
  292. data/app/views/platform/developer/help/credits.html.erb +77 -0
  293. data/app/views/platform/developer/help/index.html.erb +19 -0
  294. data/app/views/platform/developer/help/license.html.erb +586 -0
  295. data/app/views/platform/developer/help/oauth_app_login.html.erb +177 -0
  296. data/app/views/platform/developer/help/oauth_client_side.html.erb +264 -0
  297. data/app/views/platform/developer/help/oauth_desktop.html.erb +191 -0
  298. data/app/views/platform/developer/help/oauth_extensions.html.erb +342 -0
  299. data/app/views/platform/developer/help/oauth_intro.html.erb +371 -0
  300. data/app/views/platform/developer/help/oauth_mobile.html.erb +292 -0
  301. data/app/views/platform/developer/help/oauth_server_side.html.erb +603 -0
  302. data/app/views/platform/developer/help/oauth_trusted_client.html.erb +202 -0
  303. data/app/views/platform/developer/help/reference.html.erb +42 -0
  304. data/app/views/platform/developer/help/sdk_ios.html.erb +31 -0
  305. data/app/views/platform/developer/help/sdk_js.html.erb +202 -0
  306. data/app/views/platform/developer/info/_basic_info.html.erb +74 -0
  307. data/app/views/platform/developer/info/_header.html.erb +12 -0
  308. data/app/views/platform/developer/info/index.html.erb +23 -0
  309. data/app/views/platform/developer/registration/index.html.erb +134 -0
  310. data/app/views/platform/developer/resources/index.html.erb +23 -0
  311. data/app/views/platform/forum/_message.html.erb +17 -0
  312. data/app/views/platform/forum/_messages.html.erb +14 -0
  313. data/app/views/platform/forum/_new_message.html.erb +26 -0
  314. data/app/views/platform/forum/_new_topic.html.erb +38 -0
  315. data/app/views/platform/forum/_topic.html.erb +18 -0
  316. data/app/views/platform/forum/_topics.html.erb +74 -0
  317. data/app/views/platform/login/index.html.erb +31 -0
  318. data/app/views/platform/login/register.html.erb +55 -0
  319. data/app/views/platform/oauth/_authorization_box.html.erb +75 -0
  320. data/app/views/platform/oauth/_authorization_popup.html.erb +38 -0
  321. data/app/views/platform/oauth/_authorize_form.html.erb +11 -0
  322. data/app/views/platform/oauth/auth_failed.html.erb +0 -0
  323. data/app/views/platform/oauth/auth_success.html.erb +0 -0
  324. data/app/views/platform/oauth/authorize_desktop.html.erb +76 -0
  325. data/app/views/platform/oauth/authorize_failure_iframe.html.erb +1 -0
  326. data/app/views/platform/oauth/authorize_failure_mobile.html.erb +24 -0
  327. data/app/views/platform/oauth/authorize_failure_popup.html.erb +24 -0
  328. data/app/views/platform/oauth/authorize_failure_web.html.erb +1 -0
  329. data/app/views/platform/oauth/authorize_iframe.html.erb +16 -0
  330. data/app/views/platform/oauth/authorize_mobile.html.erb +1 -0
  331. data/app/views/platform/oauth/authorize_popup.html.erb +1 -0
  332. data/app/views/platform/oauth/authorize_success_iframe.html.erb +1 -0
  333. data/app/views/platform/oauth/authorize_success_mobile.html.erb +24 -0
  334. data/app/views/platform/oauth/authorize_success_popup.html.erb +24 -0
  335. data/app/views/platform/oauth/authorize_success_web.html.erb +1 -0
  336. data/app/views/platform/oauth/authorize_web.html.erb +3 -0
  337. data/app/views/platform/oauth/xd.html.erb +13 -0
  338. data/app/views/platform/ratings/_list.html.erb +30 -0
  339. data/app/views/platform/ratings/_new.html.erb +70 -0
  340. data/app/views/platform/ratings/_rating.html.erb +17 -0
  341. data/config/platform/config.yml +133 -0
  342. data/config/platform/data/default_applications.yml +39 -0
  343. data/config/platform/data/default_categories.yml +56 -0
  344. data/config/platform/data/default_permissions.yml +0 -0
  345. data/config/platform/site/features.yml +66 -0
  346. data/config/routes.rb +59 -0
  347. data/db/migrate/20110602232141_create_platform_tables.rb +262 -0
  348. data/docs/Classes.graffle +7315 -0
  349. data/docs/Classes.pdf +0 -0
  350. data/lib/generators/platform/platform_generator.rb +56 -0
  351. data/lib/generators/platform/templates/db/create_platform_tables.rb +262 -0
  352. data/lib/generators/platform/templates/layouts/platform.html.erb +49 -0
  353. data/lib/generators/platform/templates/layouts/platform_admin.html.erb +60 -0
  354. data/lib/platform.rb +6 -0
  355. data/lib/platform/api/already_jsoned_string.rb +9 -0
  356. data/lib/platform/api/proxy.rb +45 -0
  357. data/lib/platform/api/proxy/base.rb +62 -0
  358. data/lib/platform/cache.rb +78 -0
  359. data/lib/platform/config.rb +666 -0
  360. data/lib/platform/engine.rb +5 -0
  361. data/lib/platform/exception.rb +27 -0
  362. data/lib/platform/extensions/action_controller_extension.rb +65 -0
  363. data/lib/platform/extensions/action_view_extension.rb +168 -0
  364. data/lib/platform/extensions/object_extension.rb +51 -0
  365. data/lib/platform/helper.rb +33 -0
  366. data/lib/platform/logger.rb +62 -0
  367. data/lib/platform/railtie.rb +52 -0
  368. data/lib/platform/random_password_generator.rb +76 -0
  369. data/lib/platform/simple_string_permissions.rb +40 -0
  370. data/lib/platform/version.rb +3 -0
  371. data/lib/tasks/platform.rake +119 -0
  372. data/platform.gemspec +45 -0
  373. data/script/rails +6 -0
  374. data/spec/config/config_spec.rb +10 -0
  375. data/spec/dummy_app.rb +52 -0
  376. data/spec/models/application_spec.rb +53 -0
  377. data/spec/models/developer_spec.rb +23 -0
  378. data/spec/spec_helper.rb +29 -0
  379. data/test/dummy/Rakefile +7 -0
  380. data/test/dummy/app/assets/javascripts/application.js +7 -0
  381. data/test/dummy/app/assets/stylesheets/admin.css +200 -0
  382. data/test/dummy/app/assets/stylesheets/application.css +47 -0
  383. data/test/dummy/app/assets/stylesheets/components.css.scss +211 -0
  384. data/test/dummy/app/assets/stylesheets/layout.css.scss +143 -0
  385. data/test/dummy/app/controllers/admin/admins_controller.rb +7 -0
  386. data/test/dummy/app/controllers/admin/base_controller.rb +12 -0
  387. data/test/dummy/app/controllers/admin/bookmarks_controller.rb +7 -0
  388. data/test/dummy/app/controllers/admin/users_controller.rb +19 -0
  389. data/test/dummy/app/controllers/api/base_controller.rb +5 -0
  390. data/test/dummy/app/controllers/api/bookmarks_controller.rb +35 -0
  391. data/test/dummy/app/controllers/api/users_controller.rb +19 -0
  392. data/test/dummy/app/controllers/application_controller.rb +31 -0
  393. data/test/dummy/app/controllers/home_controller.rb +7 -0
  394. data/test/dummy/app/controllers/login_controller.rb +65 -0
  395. data/test/dummy/app/helpers/application_helper.rb +9 -0
  396. data/test/dummy/app/helpers/home_helper.rb +2 -0
  397. data/test/dummy/app/mailers/.gitkeep +0 -0
  398. data/test/dummy/app/models/.gitkeep +0 -0
  399. data/test/dummy/app/models/admin.rb +4 -0
  400. data/test/dummy/app/models/admin_filter.rb +7 -0
  401. data/test/dummy/app/models/bookmark.rb +7 -0
  402. data/test/dummy/app/models/user.rb +34 -0
  403. data/test/dummy/app/views/admin/admins/index.html.erb +7 -0
  404. data/test/dummy/app/views/admin/bookmarks/index.html.erb +5 -0
  405. data/test/dummy/app/views/admin/users/index.html.erb +10 -0
  406. data/test/dummy/app/views/demo/index.rhtml +108 -0
  407. data/test/dummy/app/views/demo/tokens.rhtml +35 -0
  408. data/test/dummy/app/views/home/index.html.erb +43 -0
  409. data/test/dummy/app/views/layouts/_footer.html.erb +16 -0
  410. data/test/dummy/app/views/layouts/_header.html.erb +22 -0
  411. data/test/dummy/app/views/layouts/admin.html.erb +97 -0
  412. data/test/dummy/app/views/layouts/application.html.erb +25 -0
  413. data/test/dummy/app/views/layouts/minimal.html.erb +37 -0
  414. data/test/dummy/app/views/layouts/popup.html.erb +43 -0
  415. data/test/dummy/app/views/login/index.html.erb +34 -0
  416. data/test/dummy/app/views/login/register.html.erb +51 -0
  417. data/test/dummy/config.ru +4 -0
  418. data/test/dummy/config/application.rb +51 -0
  419. data/test/dummy/config/boot.rb +10 -0
  420. data/test/dummy/config/database.yml +25 -0
  421. data/test/dummy/config/environment.rb +5 -0
  422. data/test/dummy/config/environments/development.rb +30 -0
  423. data/test/dummy/config/environments/production.rb +60 -0
  424. data/test/dummy/config/environments/test.rb +42 -0
  425. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  426. data/test/dummy/config/initializers/inflections.rb +10 -0
  427. data/test/dummy/config/initializers/mime_types.rb +5 -0
  428. data/test/dummy/config/initializers/secret_token.rb +7 -0
  429. data/test/dummy/config/initializers/session_store.rb +8 -0
  430. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  431. data/test/dummy/config/locales/en.yml +5 -0
  432. data/test/dummy/config/platform/api/0/bookmark.yml +18 -0
  433. data/test/dummy/config/platform/api/0/user.yml +17 -0
  434. data/test/dummy/config/platform/api/1/bookmark.yml +58 -0
  435. data/test/dummy/config/platform/api/1/user.yml +36 -0
  436. data/test/dummy/config/platform/config.yml +135 -0
  437. data/test/dummy/config/platform/data/default_applications.yml +39 -0
  438. data/test/dummy/config/platform/data/default_categories.yml +56 -0
  439. data/test/dummy/config/platform/data/default_permissions.yml +0 -0
  440. data/test/dummy/config/platform/site/features.yml +66 -0
  441. data/test/dummy/config/platform/site/sample_apps.yml +100 -0
  442. data/test/dummy/config/routes.rb +30 -0
  443. data/test/dummy/config/tr8n/config.yml +247 -0
  444. data/test/dummy/config/tr8n/data/ip_locations.csv +93460 -0
  445. data/test/dummy/config/tr8n/rules/default_date_rules.yml +20 -0
  446. data/test/dummy/config/tr8n/rules/default_gender_list_rules.yml +82 -0
  447. data/test/dummy/config/tr8n/rules/default_gender_rules.yml +20 -0
  448. data/test/dummy/config/tr8n/rules/default_language_cases.yml +272 -0
  449. data/test/dummy/config/tr8n/rules/default_list_rules.yml +19 -0
  450. data/test/dummy/config/tr8n/rules/default_numeric_rules.yml +42 -0
  451. data/test/dummy/config/tr8n/rules/default_value_rules.yml +18 -0
  452. data/test/dummy/config/tr8n/site/default_glossary.yml +18 -0
  453. data/test/dummy/config/tr8n/site/default_languages.yml +1591 -0
  454. data/test/dummy/config/tr8n/site/features.yml +111 -0
  455. data/test/dummy/config/tr8n/site/shortcuts.yml +55 -0
  456. data/test/dummy/config/tr8n/site/sitemap.json +42 -0
  457. data/test/dummy/config/tr8n/tokens/data.yml +19 -0
  458. data/test/dummy/config/tr8n/tokens/decorations.yml +19 -0
  459. data/test/dummy/config/will_filter/config.yml +99 -0
  460. data/test/dummy/db/migrate/20101207014543_create_users.rb +23 -0
  461. data/test/dummy/db/migrate/20110113223509_create_admins.rb +15 -0
  462. data/test/dummy/db/migrate/20110930041143_create_will_filter_filters.rb +15 -0
  463. data/test/dummy/db/migrate/20110930041150_create_tr8n_tables.rb +350 -0
  464. data/test/dummy/db/migrate/20111004075531_create_platform_tables.rb +262 -0
  465. data/test/dummy/db/migrate/20111012055603_create_bookmarks.rb +10 -0
  466. data/test/dummy/db/schema.rb +683 -0
  467. data/test/dummy/lib/assets/.gitkeep +0 -0
  468. data/test/dummy/lib/platform/api/bookmark_proxy_0.rb +12 -0
  469. data/test/dummy/lib/platform/api/bookmark_proxy_1.rb +12 -0
  470. data/test/dummy/lib/platform/api/user_proxy_0.rb +12 -0
  471. data/test/dummy/lib/platform/api/user_proxy_1.rb +12 -0
  472. data/test/dummy/log/.gitkeep +0 -0
  473. data/test/dummy/public/404.html +26 -0
  474. data/test/dummy/public/422.html +26 -0
  475. data/test/dummy/public/500.html +26 -0
  476. data/test/dummy/public/favicon.ico +0 -0
  477. data/test/dummy/script/rails +6 -0
  478. data/test/dummy/test/fixtures/documents.yml +11 -0
  479. data/test/dummy/test/unit/document_test.rb +7 -0
  480. metadata +886 -0
@@ -0,0 +1,74 @@
1
+ #--
2
+ # Copyright (c) 2011 Michael Berkovich
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ class Platform::ForumController < Platform::BaseController
25
+
26
+ def new_message
27
+ app = Platform::Application.find(params[:app_id])
28
+ if params[:topic_id]
29
+ topic = Platform::ForumTopic.find_by_id(params[:topic_id])
30
+ else
31
+ topic = Platform::ForumTopic.create(:subject => app, :user => Platform::Config.current_user, :topic => params[:topic])
32
+ end
33
+
34
+ Platform::ForumMessage.create(:topic => topic, :message => params[:message], :user => Platform::Config.current_user)
35
+ redirect_to(:controller => "/platform/apps", :action => :view, :id => app.id, :sec => 'Discussions', :topic_id => topic.id, :last_page => true)
36
+ end
37
+
38
+ def delete_topic
39
+ topic = Platform::ForumTopic.find_by_id(params[:topic_id])
40
+
41
+ unless topic
42
+ trfe("This topic does not exist")
43
+ return redirect_to_source
44
+ end
45
+
46
+ if topic.user != platform_current_user
47
+ trfe("You cannot delete topics you didn't create.")
48
+ return redirect_to_source
49
+ end
50
+
51
+ topic.destroy
52
+ trfn("The topic {topic} has been removed", nil, :topic => "\"#{topic.topic}\"")
53
+ redirect_to_source
54
+ end
55
+
56
+ def delete_message
57
+ message = Platform::ForumMessage.find_by_id(params[:message_id])
58
+
59
+ unless message
60
+ trfe("This message does not exist")
61
+ return redirect_to_source
62
+ end
63
+
64
+ if message.user != platform_current_user
65
+ trfe("You cannot delete messages you didn't post.")
66
+ return redirect_to_source
67
+ end
68
+
69
+ message.destroy
70
+ trfn("The message has been removed")
71
+ redirect_to_source
72
+ end
73
+
74
+ end
@@ -0,0 +1,421 @@
1
+ #--
2
+ # Copyright (c) 2011 Michael Berkovich
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ # OAuth 2.0 Spec URL: http://tools.ietf.org/html/draft-ietf-oauth-v2-20
25
+ class Platform::OauthController < Platform::BaseController
26
+ # ssl_required :authorize, :request_token, :invalidate_token, :validate_token, :revoke, :invalidate, :auth_success
27
+
28
+ skip_before_filter :validate_guest_user
29
+
30
+ # http://tools.ietf.org/html/draft-ietf-oauth-v2-16#section-4.1
31
+ # supports response_type = code, token
32
+ def authorize
33
+ if request_param(:client_id).blank?
34
+ return redirect_with_response(:error_description => "client_id must be provided", :error => :invalid_request)
35
+ end
36
+
37
+ unless client_application
38
+ return redirect_with_response(:error_description => "invalid client application id", :error => :unauthorized_client)
39
+ end
40
+
41
+ platform_store_oauth_redirect_params
42
+
43
+ if platform_current_user_is_guest?
44
+ return redirect_to(platform_login_url)
45
+ end
46
+
47
+ if redirect_url_required? and redirect_url.blank?
48
+ return redirect_with_response(:error_description => "redirect_uri must be provided as a parameter or in the application callback_url property", :error => :invalid_request)
49
+ end
50
+
51
+ unless ["code","token"].include?(response_type)
52
+ return redirect_with_response(:error_description => "only code and token response types are currently supported", :error => :unsupported_response_type)
53
+ end
54
+
55
+ unless redirect_url_valid?(redirect_url)
56
+ return redirect_with_response(:error_description => "redirect_uri cannot point to a different server than from the one it sent a request", :error => :invalid_request)
57
+ end
58
+
59
+ send("oauth2_authorize_#{response_type}")
60
+ end
61
+
62
+ # http://tools.ietf.org/html/draft-ietf-oauth-v2-16#section-4.2
63
+ # supported grant_type = authorization_code, password, refresh_token, client_credentials
64
+ def request_token
65
+ if request_param(:client_id).blank?
66
+ return render_response(:error_description => "client_id must be provided", :error => :invalid_request)
67
+ end
68
+
69
+ unless client_application
70
+ return render_response(:error_description => "invalid client application id", :error => :unauthorized_client)
71
+ end
72
+
73
+ unless ["authorization_code", "password", "refresh_token", "client_credentials"].include?(grant_type)
74
+ return render_response(:error_description => "only authorization_code, password and refresh_token grant types are currently supported", :error => :unsupported_grant_type)
75
+ end
76
+
77
+ send("oauth2_request_token_#{grant_type}")
78
+ end
79
+ alias :token :request_token
80
+
81
+ def auth_success
82
+ render :layout => false
83
+ end
84
+
85
+ def auth_failed
86
+ render :layout => false
87
+ end
88
+
89
+ def validate_token
90
+ token = Platform::Oauth::OauthToken.find_by_token(request_param(:access_token))
91
+ if token && token.authorized?
92
+ render_response(:result => "OK")
93
+ else
94
+ render_response(:error => :invalid_token, :error_description => "invalid token")
95
+ end
96
+ end
97
+
98
+ # add jsonp support
99
+ def invalidate_token
100
+ token = Platform::Oauth::OauthToken.find_by_token(request_param(:access_token))
101
+ token.invalidate! if token
102
+ render_response(:result => "OK")
103
+ end
104
+
105
+ def deauthorize
106
+ unless Platform::Config.current_user_is_guest?
107
+ client_application.deauthorize_user if client_application
108
+ end
109
+ render_response(:result => "OK")
110
+ end
111
+
112
+ def logout
113
+ if Platform::Config.site_user_info_enabled?
114
+ begin
115
+ eval(Platform::Config.logout_method)
116
+ rescue Exception => ex
117
+ raise Platform::Exception.new("Failed to execute #{Platform::Config.logout_method} with exception: #{ex.message}")
118
+ end
119
+ else
120
+ # handle default logout strategy
121
+ end
122
+
123
+ render_response(:result => "OK")
124
+ end
125
+
126
+ def xd?
127
+ ['popup', 'hidden'].include?(display)
128
+ end
129
+
130
+ def xd
131
+ render :layout => false
132
+ end
133
+
134
+ # XD only method - for now
135
+ def xd_status
136
+ if params[:origin].blank?
137
+ return redirect_with_response(:status => "unknown", :error => :invalid_request, :error_description => "origin must be specified")
138
+ end
139
+
140
+ unless client_application
141
+ return redirect_with_response(:status => "unknown", :error => :invalid_request, :error_description => "client_id must be specified")
142
+ end
143
+
144
+ uri = URI.parse(params[:origin])
145
+ unless uri.host == client_application.site_domain
146
+ return redirect_with_response(:status => "unknown", :error => :invalid_request, :error_description => "Anauthorized access - invalid origin.")
147
+ end
148
+
149
+ if Platform::Config.current_user_is_guest?
150
+ return redirect_with_response(:status => "unknown")
151
+ end
152
+
153
+ # implement authorized user
154
+ if client_application.authorized_user?
155
+ # add access token to the redirect
156
+ access_token = client_application.create_access_token(:user=>Geni.current_user, :scope=>scope)
157
+ refresh_token = client_application.create_refresh_token(:user=>Geni.current_user, :scope=>scope)
158
+ return redirect_with_response(:status => "authorized", :access_token => access_token.token, :refresh_token => refresh_token.token, :expires_in => (access_token.valid_to.to_i - Time.now.to_i))
159
+ end
160
+
161
+ redirect_with_response(:status => "unauthorized")
162
+ end
163
+
164
+ private
165
+
166
+ def request_param(key)
167
+ params[key]
168
+ end
169
+
170
+ def client_application
171
+ return nil if request_param(:client_id).blank?
172
+ @client_application ||= Platform::Application.for(request_param(:client_id))
173
+ end
174
+
175
+ def redirect_url
176
+ @redirect_url ||= request_param(:redirect_url) || request_param(:redirect_uri) || client_application.try(:callback_url)
177
+ end
178
+
179
+ def redirect_url_required?
180
+ return false if xd? or desktop?
181
+ true
182
+ end
183
+
184
+ # web_server, user_agent
185
+ def type
186
+ @type ||= request_param(:type) || "web_server"
187
+ end
188
+
189
+ def scope
190
+ @scope ||= request_param(:scope) || "basic"
191
+ end
192
+
193
+ def grant_type
194
+ @grant_type ||= request_param(:grant_type) || "authorization_code"
195
+ end
196
+
197
+ def response_type
198
+ @response_type ||= request_param(:response_type) || "code"
199
+ end
200
+
201
+ def display
202
+ @display ||= begin
203
+ if mobile_device?
204
+ "mobile"
205
+ elsif params[:display]
206
+ params[:display]
207
+ else
208
+ "web"
209
+ end
210
+ end
211
+ end
212
+
213
+ def jsonp?
214
+ not params[:callback].blank?
215
+ end
216
+
217
+ def desktop?
218
+ display == "desktop"
219
+ end
220
+
221
+ def iframe?
222
+ display == "iframe"
223
+ end
224
+
225
+ def mobile?
226
+ display == "mobile"
227
+ end
228
+
229
+ # needs to be configured through Platform::Config
230
+ def authenticate_user(username, password)
231
+ User.authenticate(username, password)
232
+ end
233
+
234
+ # request token with grant_type = authorization_code
235
+ def oauth2_request_token_authorization_code
236
+ if request_param(:code).blank?
237
+ return render_response(:error_description => "code must be provided", :error => :invalid_request)
238
+ end
239
+
240
+ request_token = Platform::Oauth::RequestToken.find(:first, :conditions => ["application_id = ? and token = ? and valid_to > ? and invalidated_at is null",
241
+ client_application.id, request_param(:code), Time.now])
242
+ unless request_token
243
+ return render_response(:error_description => "invalid verification code", :error => :invalid_request)
244
+ end
245
+
246
+ if request_token.callback_url != redirect_url
247
+ return render_response(:error_description => "redirection url must match the url used for the code request", :error => :invalid_request)
248
+ end
249
+
250
+ access_token = request_token.exchange!
251
+ refresh_token = client_application.create_refresh_token(:user=>access_token.user, :scope=>scope)
252
+ render_response(:access_token => access_token.token, :refresh_token => refresh_token.token, :expires_in => (access_token.valid_to.to_i - Time.now.to_i))
253
+ end
254
+
255
+ # request token with grant_type = password
256
+ def oauth2_request_token_password
257
+ unless client_application.allow_grant_type_password?
258
+ return render_response(:error_description => "this application is not authorized to use grant_type password", :error => :unauthorized_application)
259
+ end
260
+
261
+ if request_param(:username).blank?
262
+ return render_response(:error_description => "username must be provided", :error => :invalid_request)
263
+ end
264
+
265
+ if request_param(:password).nil?
266
+ return render_response(:error_description => "password must be provided", :error => :invalid_request)
267
+ end
268
+
269
+ user = authenticate_user(request_param(:username), request_param(:password))
270
+ unless user
271
+ return render_response(:error_description => "invalid username and/or password", :error => :invalid_request)
272
+ end
273
+
274
+ access_token = client_application.create_access_token(:user=>user, :scope=>scope)
275
+ refresh_token = client_application.create_refresh_token(:user=>user, :scope=>scope)
276
+ render_response(:access_token => access_token.token, :refresh_token => refresh_token.token, :expires_in => (access_token.valid_to.to_i - Time.now.to_i))
277
+ end
278
+
279
+ # request token with grant_type = client_credentials
280
+ def oauth2_request_token_client_credentials
281
+ unless client_application.allow_grant_type_client_credentials?
282
+ return render_response(:error_description => "this application is not authorized to use grant_type client_credentials", :error => :unauthorized_application)
283
+ end
284
+
285
+ client_token = client_application.create_client_token(:scope=>scope)
286
+ refresh_token = client_application.create_refresh_token(:scope=>scope)
287
+ render_response(:access_token => client_token.token, :refresh_token => refresh_token.token, :expires_in => (client_token.valid_to.to_i - Time.now.to_i))
288
+ end
289
+
290
+ # request token with grant_type = refresh_token
291
+ def oauth2_request_token_refresh_token
292
+ if request_param(:refresh_token).blank?
293
+ return render_response(:error_description => "refresh_token must be provided", :error => :invalid_request)
294
+ end
295
+
296
+ refresh_token = Platform::Oauth::RefreshToken.find(:first, :conditions => ["application_id = ? and token = ? and invalidated_at is null", client_application.id, request_param(:refresh_token)])
297
+ unless refresh_token
298
+ return render_response(:error_description => "invalid refresh token", :error => :invalid_request)
299
+ end
300
+
301
+ access_token = refresh_token.exchange!
302
+ refresh_token = client_application.create_refresh_token(:user=>access_token.user, :scope=>scope)
303
+ render_response(:access_token => access_token.token, :refresh_token => refresh_token.token, :expires_in => (access_token.valid_to.to_i - Time.now.to_i))
304
+ end
305
+
306
+ # authorize with response_type = code
307
+ def oauth2_authorize_code
308
+ if request.post?
309
+ platform_remove_oauth_redirect_params
310
+
311
+ if params[:authorize] == '1'
312
+ Platform::ApplicationUser.touch(client_application)
313
+ code = client_application.create_request_token(:user=>Platform::Config.current_user, :callback_url=>redirect_url, :scope => scope)
314
+ return redirect_with_response(:code => code.code, :expires_in => (code.valid_to.to_i - Time.now.to_i))
315
+ end
316
+
317
+ if iframe? and client_application.auto_signin?
318
+ return redirect_to(Platform::Config.default_url)
319
+ end
320
+
321
+ return redirect_with_response(:status => :unauthorized, :message => "canceled")
322
+ end
323
+
324
+ render_action("authorize")
325
+ end
326
+
327
+ # authorize with response_type = token
328
+ def oauth2_authorize_token
329
+ if request.post?
330
+ platform_remove_oauth_redirect_params
331
+
332
+ if params[:authorize] == '1'
333
+ Platform::ApplicationUser.touch(client_application)
334
+ access_token = client_application.create_access_token(:user=>Platform::Config.current_user, :scope=>scope)
335
+ return redirect_with_response(:access_token => access_token.token, :expires_in => (access_token.valid_to.to_i - Time.now.to_i))
336
+ end
337
+
338
+ if iframe? and client_application.auto_signin?
339
+ return redirect_to(Platform::Config.default_url)
340
+ end
341
+
342
+ return redirect_with_response(:status => :unauthorized, :message => "canceled")
343
+ end
344
+
345
+ render_action("authorize")
346
+ end
347
+
348
+ def redirect_url_valid?(url)
349
+ return true if xd?
350
+
351
+ begin
352
+ URI.parse(url)
353
+ rescue
354
+ return false
355
+ end
356
+
357
+ true
358
+ end
359
+
360
+ # used by the authorization process
361
+ def redirect_with_response(response_params, opts = {})
362
+ response_params = HashWithIndifferentAccess.new(response_params)
363
+
364
+ # preserve state
365
+ response_params[:state] = request_param(:state) if request_param(:state)
366
+
367
+ # more scope validation must be done
368
+ response_params[:scope] = request_param(:scope) if request_param(:scope)
369
+
370
+ # process xd popup
371
+ if xd?
372
+ params.merge!(response_params)
373
+ return render(:action => :xd, :layout => false)
374
+ end
375
+
376
+ response_query = response_params.collect{|n,v| "#{n}=#{CGI.escape(v.to_s)}"}.join("&")
377
+
378
+ # for desktop apps - redirect to local urls
379
+ if desktop?
380
+ if response_params[:error_description] or response_params[:status] == 'unauthorized'
381
+ return redirect_to(:action => :auth_failed, :anchor => response_query)
382
+ else
383
+ return redirect_to(:action => :auth_success, :anchor => response_query)
384
+ end
385
+ end
386
+
387
+ if redirect_url_required? and redirect_url.blank?
388
+ @error = response_params[:error_description]
389
+ return render_action("authorize_failure")
390
+ end
391
+
392
+ redirect_uri = URI.parse(redirect_url)
393
+ redirect_uri.path = (redirect_uri.path.blank? ? "/" : redirect_uri.path) unless mobile? # mobile apps will not have path
394
+ redirect_uri.query = redirect_uri.query.blank? ? response_query : redirect_uri.query + "&#{response_query}"
395
+
396
+ redirect_to(redirect_uri.to_s)
397
+ end
398
+
399
+ # used by the request token process
400
+ def render_response(response_params, opts = {})
401
+ response_params = HashWithIndifferentAccess.new(response_params)
402
+
403
+ # preserve state
404
+ response_params[:state] = request_param(:state) if request_param(:state)
405
+
406
+ # more scope validation must be done
407
+ response_params[:scope] = request_param(:scope) if request_param(:scope)
408
+
409
+ # we need to support json and redirect based method as well
410
+ if jsonp?
411
+ render(:text => "#{params[:callback].strip}(#{response_params.to_json})")
412
+ else
413
+ render(:json => response_params.to_json)
414
+ end
415
+ end
416
+
417
+ def render_action(action)
418
+ render(:action => "#{action}_#{display}", :layout => Platform::Config.site_info["oauth_#{display}_layout"])
419
+ end
420
+
421
+ end