├── .gitignore ├── README.md ├── clients └── ruby │ ├── .gitignore │ ├── Gemfile │ ├── LICENSE.txt │ ├── README.md │ ├── Rakefile │ ├── lib │ ├── openkit.rb │ └── openkit │ │ ├── request.rb │ │ ├── request │ │ ├── base.rb │ │ ├── base_delegate.rb │ │ ├── delete.rb │ │ ├── get.rb │ │ ├── post.rb │ │ ├── post_multipart.rb │ │ ├── put.rb │ │ └── upload.rb │ │ └── version.rb │ ├── openkit.gemspec │ └── test │ ├── api │ ├── score_api_test.rb │ └── user_api_test.rb │ └── test_helper.rb ├── dashboard ├── AGPL-License.txt ├── Capfile ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── app │ ├── assets │ │ ├── fonts │ │ │ ├── Elusive-Icons.dev.svg │ │ │ ├── Elusive-Icons.eot │ │ │ ├── Elusive-Icons.svg │ │ │ ├── Elusive-Icons.ttf │ │ │ └── Elusive-Icons.woff │ │ ├── images │ │ │ ├── achievement_dash.png │ │ │ ├── android_icon.png │ │ │ ├── app_icon.png │ │ │ ├── bg.png │ │ │ ├── cloud_dash.png │ │ │ ├── cloud_icon.png │ │ │ ├── invites_dash.png │ │ │ ├── ios_icon.png │ │ │ ├── leaderboard_dash.png │ │ │ ├── login_logo.png │ │ │ ├── logo.png │ │ │ ├── multiplayer_dash.png │ │ │ ├── photon-server-logo.png │ │ │ ├── photon-slide.png │ │ │ ├── push_dash.png │ │ │ ├── rails.png │ │ │ └── unity_icon.png │ │ ├── javascripts │ │ │ ├── application.js │ │ │ ├── classie.js │ │ │ ├── custom.js │ │ │ └── modalEffects.js │ │ └── stylesheets │ │ │ ├── application.css.scss │ │ │ ├── component.css.scss │ │ │ ├── elusive-webfont.css.scss │ │ │ ├── general.css.scss │ │ │ ├── layout.css.scss │ │ │ ├── mixins.css.scss │ │ │ └── reset.css.scss │ ├── controllers │ │ ├── api │ │ │ ├── v08 │ │ │ │ ├── achievement_scores_controller.rb │ │ │ │ ├── achievements_controller.rb │ │ │ │ ├── application_controller.rb │ │ │ │ ├── apps_controller.rb │ │ │ │ ├── best_scores_controller.rb │ │ │ │ ├── leaderboards_controller.rb │ │ │ │ ├── scores_controller.rb │ │ │ │ └── users_controller.rb │ │ │ ├── v09 │ │ │ │ ├── achievement_scores_controller.rb │ │ │ │ ├── achievements_controller.rb │ │ │ │ ├── application_controller.rb │ │ │ │ ├── apps_controller.rb │ │ │ │ ├── best_scores_controller.rb │ │ │ │ ├── leaderboards_controller.rb │ │ │ │ ├── scores_controller.rb │ │ │ │ └── users_controller.rb │ │ │ └── v1 │ │ │ │ ├── achievement_scores_controller.rb │ │ │ │ ├── achievements_controller.rb │ │ │ │ ├── application_controller.rb │ │ │ │ ├── apps_controller.rb │ │ │ │ ├── best_scores_controller.rb │ │ │ │ ├── challenges_controller.rb │ │ │ │ ├── client_sessions_controller.rb │ │ │ │ ├── features_controller.rb │ │ │ │ ├── leaderboards_controller.rb │ │ │ │ ├── scores_controller.rb │ │ │ │ └── users_controller.rb │ │ └── dashboard │ │ │ ├── achievement_scores_controller.rb │ │ │ ├── achievements_controller.rb │ │ │ ├── application_controller.rb │ │ │ ├── apps_controller.rb │ │ │ ├── change_password_controller.rb │ │ │ ├── developer_sessions_controller.rb │ │ │ ├── developers_controller.rb │ │ │ ├── leaderboards_controller.rb │ │ │ ├── password_resets_controller.rb │ │ │ ├── production_push_certs_controller.rb │ │ │ ├── push_notes_controller.rb │ │ │ ├── sandbox_push_certs_controller.rb │ │ │ ├── scores_controller.rb │ │ │ └── turns_controller.rb │ ├── helpers │ │ ├── achievement_scores_helper.rb │ │ ├── achievements_helper.rb │ │ ├── application_helper.rb │ │ ├── apps_helper.rb │ │ ├── change_password_helper.rb │ │ ├── leaderboards_helper.rb │ │ ├── password_resets_helper.rb │ │ ├── scores_helper.rb │ │ └── users_helper.rb │ ├── mailers │ │ ├── .gitkeep │ │ └── developer_mailer.rb │ ├── models │ │ ├── .gitkeep │ │ ├── achievement.rb │ │ ├── achievement_score.rb │ │ ├── api_whitelist.rb │ │ ├── app.rb │ │ ├── base_achievement_score.rb │ │ ├── base_client_session.rb │ │ ├── base_score.rb │ │ ├── base_token.rb │ │ ├── challenge.rb │ │ ├── change_password.rb │ │ ├── client_session.rb │ │ ├── developer.rb │ │ ├── developer_session.rb │ │ ├── leaderboard.rb │ │ ├── oauth_nonce.rb │ │ ├── production_push_cert.rb │ │ ├── push_cert.rb │ │ ├── sandbox_achievement_score.rb │ │ ├── sandbox_client_session.rb │ │ ├── sandbox_push_cert.rb │ │ ├── sandbox_score.rb │ │ ├── sandbox_token.rb │ │ ├── score.rb │ │ ├── subscription.rb │ │ ├── token.rb │ │ ├── turn.rb │ │ └── user.rb │ └── views │ │ ├── dashboard │ │ ├── achievements │ │ │ ├── _form.html.erb │ │ │ ├── edit.html.erb │ │ │ ├── index.html.erb │ │ │ ├── new.html.erb │ │ │ └── show.html.erb │ │ ├── apps │ │ │ ├── _form.html.erb │ │ │ ├── edit.html.erb │ │ │ ├── index.html.erb │ │ │ ├── new.html.erb │ │ │ └── show.html.erb │ │ ├── change_password │ │ │ ├── _form.html.erb │ │ │ └── new.html.erb │ │ ├── developer_mailer │ │ │ └── password_reset_instructions.html.erb │ │ ├── developer_sessions │ │ │ ├── _form.html.erb │ │ │ └── new.html.erb │ │ ├── developers │ │ │ ├── _form.html.erb │ │ │ ├── edit.html.erb │ │ │ ├── new.html.erb │ │ │ └── show.html.erb │ │ ├── leaderboards │ │ │ ├── _form.html.erb │ │ │ ├── edit.html.erb │ │ │ ├── index.html.erb │ │ │ ├── new.html.erb │ │ │ └── show.html.erb │ │ ├── password_resets │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── production_push_certs │ │ │ └── new.html.erb │ │ ├── push_notes │ │ │ └── info.html.erb │ │ ├── sandbox_push_certs │ │ │ ├── new.html.erb │ │ │ └── test_push.html.erb │ │ └── turns │ │ │ └── new.html.erb │ │ └── layouts │ │ └── application.html.erb ├── bin │ ├── bundle │ ├── rails │ └── rake ├── config.ru ├── config │ ├── application.rb │ ├── boot.rb │ ├── database.yml │ ├── deploy.rb │ ├── deploy │ │ ├── production.rb │ │ └── staging.rb │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── backtrace_silencers.rb │ │ ├── custom_initializer.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── secret_token.rb │ │ ├── session_store.rb │ │ ├── setup_mail.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ └── en.yml │ ├── ok_config.rb │ ├── routes.rb │ └── unicorn.conf.rb ├── custom_plan.rb ├── db │ ├── migrate │ │ ├── 20121211232400_create_leaderboards.rb │ │ ├── 20121212003310_create_apps.rb │ │ ├── 20121213235802_rename_games_applications.rb │ │ ├── 20121214010230_create_developers.rb │ │ ├── 20121214012407_rename_applications_apps.rb │ │ ├── 20121214041237_add_authlogic_field_to_developers.rb │ │ ├── 20121214044630_add_slug_to_apps.rb │ │ ├── 20121214054142_remove_unique_from_app_slug.rb │ │ ├── 20121214104910_add_attachment_icon_header_image_to_leaderboards.rb │ │ ├── 20121214204641_add_in_development_to_leaderboards.rb │ │ ├── 20121215012621_create_users.rb │ │ ├── 20121215055142_add_type_column_to_leaderboards.rb │ │ ├── 20121215073551_create_scores.rb │ │ ├── 20121222210457_add_app_key_to_apps.rb │ │ ├── 20121224195721_add_developer_id_to_users.rb │ │ ├── 20121224201402_create_subscriptions.rb │ │ ├── 20121226022857_drop_attached_header_from_leaderboards.rb │ │ ├── 20121226023835_add_icon_to_apps.rb │ │ ├── 20121228191043_drop_sti_from_leaderboards.rb │ │ ├── 20130102201852_add_perishable_token_to_developers.rb │ │ ├── 20130104032036_create_delayed_jobs.rb │ │ ├── 20130104064711_add_fb_id_and_twitter_id_to_users.rb │ │ ├── 20130121094006_specify_precision_on_floats.rb │ │ ├── 20130131234141_add_composite_index_on_scores.rb │ │ ├── 20130206025130_drop_header_from_apps.rb │ │ ├── 20130322231927_scores_rearch.rb │ │ ├── 20130412231348_add_metadata_to_base_score.rb │ │ ├── 20130416004410_add_display_string_to_scores.rb │ │ ├── 20130416225733_make_scores_big_ints.rb │ │ ├── 20130417023019_rename_value_to_sort_value.rb │ │ ├── 20130417232335_create_achievements.rb │ │ ├── 20130417235451_add_desc_to_achievements.rb │ │ ├── 20130418021336_add_points_to_achievements.rb │ │ ├── 20130418021401_add_goal_to_achievements.rb │ │ ├── 20130418150745_add_custom_id_to_ok_users.rb │ │ ├── 20130420180955_create_achievement_progress.rb │ │ ├── 20130423235151_rename_achievement_progress.rb │ │ ├── 20130425202438_remove_appid_from_achievement_scores.rb │ │ ├── 20130426174146_add_fbid_to_apps.rb │ │ ├── 20130426221939_achievements_touchup.rb │ │ ├── 20130430072017_create_oauth_tables.rb │ │ ├── 20130430215726_drop_oauth_plugin_tables.rb │ │ ├── 20130430220215_add_secret_key_to_apps.rb │ │ ├── 20130502211458_add_google_id_to_users.rb │ │ ├── 20130510025425_drop_best_scores_tables.rb │ │ ├── 20130613013602_add_gamecenter_id_to_users.rb │ │ ├── 20130613190346_add_game_center_and_google_to_leaderboard.rb │ │ ├── 20130711040819_add_priority_to_leaderboards.rb │ │ ├── 20130803170905_add_meta_doc_to_scores.rb │ │ ├── 20130809000348_index_scores_on_sort_value.rb │ │ ├── 20130819221046_service_ids_as_strings.rb │ │ ├── 20130826194151_acts_as_taggable_on_migration.rb │ │ ├── 20130829135119_create_client_sessions.rb │ │ ├── 20130829150430_add_app_id_to_client_sessions.rb │ │ ├── 20130829152319_create_tokens.rb │ │ ├── 20130911000023_create_api_whitelists.rb │ │ ├── 20130919003718_create_sandbox_scores.rb │ │ ├── 20130919003905_create_sandbox_achievement_scores.rb │ │ ├── 20130924235216_create_sandbox_sessions_and_tokens.rb │ │ ├── 20131021235134_add_feature_list_to_apps.rb │ │ ├── 20131031062709_drop_in_development.rb │ │ ├── 20131031154407_create_turns.rb │ │ └── 20131212071708_drop_slug_from_apps.rb │ └── schema.rb ├── files │ └── OKPushTest │ │ ├── OKPushTest.xcodeproj │ │ └── project.pbxproj │ │ └── OKPushTest │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Info-Template.plist │ │ └── main.m ├── lib │ ├── apple_push │ │ ├── README.md │ │ ├── apple_push.rb │ │ └── apple_push │ │ │ ├── connection.rb │ │ │ ├── note.rb │ │ │ └── pusher.rb │ ├── assets │ │ └── .gitkeep │ ├── capistrano │ │ ├── git_strategy.rb │ │ ├── log_invocations.rb │ │ └── tasks │ │ │ ├── bundler_mysql_install.cap │ │ │ ├── unicorn.cap │ │ │ └── unicorn_helper.rb │ ├── color_print.rb │ ├── feature_array.rb │ ├── ok_redis.rb │ ├── paperclip_helper.rb │ ├── push_loop.rb │ ├── push_queue.rb │ ├── push_test_project.rb │ ├── random_gen.rb │ ├── tasks │ │ ├── .gitkeep │ │ ├── maintenance.rake │ │ ├── setup.rake │ │ └── test.rake │ └── two_legged_oauth.rb ├── ok_wildcard.pem ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── crossdomain.xml │ ├── favicon.ico │ └── robots.txt ├── script │ ├── api_tester.rb │ ├── delayed_job │ ├── immafile.txt │ ├── push_test.rb │ └── rails ├── test │ ├── factories.rb │ ├── integration │ │ ├── .gitkeep │ │ ├── achievement_scores_api_test.rb │ │ ├── achievements_api_test.rb │ │ ├── leaderboards_api_test.rb │ │ ├── scores_api_test.rb │ │ └── users_api_test.rb │ ├── middleware │ │ ├── request_signature_test.rb │ │ └── request_signature_test_helper.rb │ ├── test_helper.rb │ └── unit │ │ ├── .gitkeep │ │ ├── change_password_test.rb │ │ ├── helpers │ │ ├── scores_helper_test.rb │ │ └── users_helper_test.rb │ │ ├── score_test.rb │ │ └── user_test.rb ├── vendor │ ├── assets │ │ ├── javascripts │ │ │ └── .gitkeep │ │ └── stylesheets │ │ │ └── .gitkeep │ └── plugins │ │ └── .gitkeep └── zeus.json ├── provisioning ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── bin │ ├── boot_instance │ └── create_security_groups ├── lib │ ├── bootstrap_file_writer.rb │ ├── dependency_check.rb │ └── system_config.rb └── templates │ └── bootstrap_min.userdata.erb └── system.yml.example /.gitignore: -------------------------------------------------------------------------------- 1 | *.rbc 2 | *.sassc 3 | .sass-cache 4 | capybara-*.html 5 | .rspec 6 | dashboard/.bundle 7 | dashboard/vendor/bundle 8 | dashboard/log/* 9 | dashboard/tmp/* 10 | dashboard/db/*.sqlite3 11 | dashboard/public/system/* 12 | dashboard/coverage/ 13 | dashboard/spec/tmp/* 14 | **.orig 15 | rerun.txt 16 | pickle-email-*.html 17 | .zeus.sock 18 | tmp/ 19 | system.yml 20 | provisioning/tmp/ 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Running Locally (Instructions for OS X) 2 | 3 | This guide assumes that you can work your way around a command line. Specific 4 | instructions are written for bash (the default shell on OS X), but should be 5 | easy to apply to other shells too. 6 | 7 | Make sure /usr/local/bin and /usr/local/sbin are in your PATH ahead of 8 | /usr/bin. You can check with `echo $PATH`. If they are not, add this line to 9 | `~/.bash_profile`: 10 | 11 | ``` 12 | export PATH="/usr/local/bin:/usr/local/sbin:~/bin:$PATH" 13 | ``` 14 | 15 | Next, install [homebrew](http://brew.sh/), if you haven't already. 16 | 17 | Add this to `~/.bash_profile`: 18 | 19 | # Add gem binaries to path. (See 'brew info ruby') 20 | export PATH=$(brew --prefix ruby)/bin:$PATH 21 | 22 | System dependencies: 23 | 24 | brew update 25 | brew upgrade ruby redis mysql libxml2 26 | gem pristine --all --only-executables 27 | 28 | Prepare rails project: 29 | 30 | git clone git@github.com:OpenKit/openkit-server.git 31 | cd openkit-server/dashboard 32 | bundle install 33 | bin/rake setup:prereqs 34 | bin/rake db:setup 35 | bin/rails start 36 | 37 | Testing: 38 | 39 | bin/rake db:test:prepare 40 | bin/rake test 41 | 42 | Testing with Zeus: 43 | 44 | bin/rake db:test:prepare 45 | gem install zeus 46 | zeus start 47 | zeus t 48 | 49 | 50 | For running api_tester: 51 | 52 | rake setup:api_test_app 53 | script/api_tester.rb 54 | 55 | -------------------------------------------------------------------------------- /clients/ruby/.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | -------------------------------------------------------------------------------- /clients/ruby/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in openkit.gemspec 4 | gemspec 5 | 6 | -------------------------------------------------------------------------------- /clients/ruby/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Lou Zell 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /clients/ruby/README.md: -------------------------------------------------------------------------------- 1 | # Openkit 2 | 3 | The ruby client for OpenKit's gaming backend. 4 | 5 | ## Installation 6 | 7 | gem install 'openkit' 8 | 9 | Or add the following line to your application's Gemfile: 10 | 11 | gem 'openkit' 12 | 13 | And run `bundle install` from your shell. 14 | 15 | 16 | ## Usage 17 | 18 | Get your app_key and secret_key from [https://developer.openkit.io](https://developer.openkit.io). 19 | 20 | Set credentials: 21 | 22 | OpenKit::Config.app_key = "" 23 | OpenKit::Config.secret_key = "" 24 | OpenKit::Config.skip_https = true # required unless you're using the beta-api endpoint 25 | 26 | Request examples: 27 | 28 | include OpenKit::Request 29 | 30 | # Get 31 | response = Get.new('/v1/leaderboards').perform 32 | 33 | # Post 34 | response = Post.new('/v1/users', {:nick => 'lou'}).perform 35 | 36 | # Put 37 | response = Put.new('/v1/users/:id', {:nick => 'lou z'}).perform 38 | 39 | # Multipart Post 40 | upload = Upload.new('', '') 41 | req = OpenKit::PostMultipart.new('/v1/scores', {:score => {:value => 100}}, upload) 42 | response = req.perform 43 | 44 | Parse the response: 45 | 46 | json = JSON.parse(response.body) 47 | 48 | Check the response headers: 49 | 50 | puts response.code 51 | response.header.each { |h, v| puts "#{h}: #{v}" } 52 | 53 | 54 | ## Contributing 55 | 56 | 1. Fork it 57 | 2. Create your feature branch (`git checkout -b my-new-feature`) 58 | 3. Commit your changes (`git commit -am 'Add some feature'`) 59 | 4. Push to the branch (`git push origin my-new-feature`) 60 | 5. Create new Pull Request 61 | -------------------------------------------------------------------------------- /clients/ruby/Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rake/testtask" 3 | 4 | Rake::TestTask.new do |t| 5 | t.libs << 'test' 6 | t.pattern = "test/**/*_test.rb" 7 | end 8 | -------------------------------------------------------------------------------- /clients/ruby/lib/openkit.rb: -------------------------------------------------------------------------------- 1 | module OpenKit 2 | 3 | class Config 4 | @host = 'api.openkit.io' # default 5 | class << self 6 | attr_accessor :app_key, :secret_key 7 | attr_accessor :host 8 | attr_accessor :skip_https 9 | end 10 | end 11 | end 12 | 13 | require_relative 'openkit/request' 14 | require_relative "openkit/version" 15 | 16 | -------------------------------------------------------------------------------- /clients/ruby/lib/openkit/request.rb: -------------------------------------------------------------------------------- 1 | require 'securerandom' 2 | require 'net/http' 3 | require 'net/http/post/multipart' 4 | require 'digest/hmac' 5 | require 'base64' 6 | require 'cgi' 7 | require 'json' 8 | require 'pp' 9 | 10 | require_relative 'request/base' 11 | require_relative 'request/base_delegate' 12 | require_relative 'request/get' 13 | require_relative 'request/put' 14 | require_relative 'request/delete' 15 | require_relative 'request/post' 16 | require_relative 'request/post_multipart' 17 | require_relative 'request/upload' 18 | -------------------------------------------------------------------------------- /clients/ruby/lib/openkit/request/base_delegate.rb: -------------------------------------------------------------------------------- 1 | module OpenKit 2 | module Request 3 | 4 | class BaseDelegate 5 | attr_reader :scheme, :host, :app_key, :secret_key 6 | attr_reader :path 7 | 8 | def initialize(path) 9 | raise "Don't instantiate me!" if abstract_class? 10 | 11 | raise "OpenKit::Config.host is not set." unless Config.host 12 | raise "OpenKit::Config.app_key is not set." unless Config.app_key 13 | raise "OpenKit::Config.secret_key is not set." unless Config.secret_key 14 | 15 | @scheme = Config.skip_https ? "http" : "https" 16 | @host = Config.host 17 | @app_key = Config.app_key 18 | @secret_key = Config.secret_key 19 | 20 | @path = path 21 | end 22 | 23 | def base_uri 24 | @scheme + "://" + @host 25 | end 26 | 27 | def uri 28 | @uri ||= URI(base_uri + @path) 29 | end 30 | 31 | private 32 | def abstract_class? 33 | self.class == BaseDelegate 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /clients/ruby/lib/openkit/request/delete.rb: -------------------------------------------------------------------------------- 1 | # Delete.from('/path') 2 | module OpenKit 3 | module Request 4 | 5 | class Delete < Base 6 | 7 | def self.from(path) 8 | new(path).perform 9 | end 10 | 11 | def initialize(path) 12 | super :delete, DeleteDelegate.new(path) 13 | end 14 | end 15 | 16 | 17 | class DeleteDelegate < BaseDelegate 18 | 19 | def initialize(path) 20 | super(path) 21 | end 22 | 23 | def net_request 24 | req = Net::HTTP::Delete.new(uri.request_uri) 25 | req['Content-Type'] = "application/json; charset=utf-8" 26 | req['Accept'] = "application/json" 27 | req 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /clients/ruby/lib/openkit/request/get.rb: -------------------------------------------------------------------------------- 1 | # Get.from('/path', {query_param1: 'foo'}) 2 | module OpenKit 3 | module Request 4 | 5 | class Get < Base 6 | 7 | def self.from(path, query_params = {}) 8 | new(path, query_params).perform 9 | end 10 | 11 | def initialize(path, query_params = {}) 12 | super :get, GetDelegate.new(path, query_params) 13 | @query_params = query_params 14 | end 15 | 16 | def params_in_signature 17 | super.merge(symbolize_keys(@query_params)) 18 | end 19 | 20 | private 21 | def symbolize_keys(hash) 22 | hash.keys.each {|k| hash[k.to_sym] = hash.delete(k)} 23 | hash 24 | end 25 | end 26 | 27 | 28 | class GetDelegate < BaseDelegate 29 | attr_accessor :query_params 30 | 31 | def initialize(path, query_params) 32 | super(path) 33 | @query_params = query_params 34 | end 35 | 36 | def net_request 37 | req = Net::HTTP::Get.new(uri.request_uri + "?" + params_to_query(@query_params)) 38 | req['Content-Type'] = "application/json; charset=utf-8" 39 | req['Accept'] = "application/json" 40 | req 41 | end 42 | 43 | def params_to_query(h) 44 | return '' if h.empty? 45 | h.collect { |k, v| "#{k.to_s}=#{v.to_s}" }.join('&') 46 | end 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /clients/ruby/lib/openkit/request/post.rb: -------------------------------------------------------------------------------- 1 | # Post.to('/path', {param1: 'foo'}) 2 | module OpenKit 3 | module Request 4 | 5 | class Post < Base 6 | 7 | def self.to(path, req_params) 8 | new(path, req_params).perform 9 | end 10 | 11 | def initialize(path, req_params) 12 | super :post, PostDelegate.new(path, req_params) 13 | end 14 | end 15 | 16 | 17 | class PostDelegate < BaseDelegate 18 | 19 | def initialize(path, req_params) 20 | super(path) 21 | @req_params = req_params 22 | end 23 | 24 | def net_request 25 | req = Net::HTTP::Post.new(uri.request_uri) 26 | req.set_body_internal(@req_params.to_json) 27 | req['Content-Type'] = "application/json; charset=utf-8" 28 | req['Accept'] = "application/json" 29 | req 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /clients/ruby/lib/openkit/request/post_multipart.rb: -------------------------------------------------------------------------------- 1 | # upload = Upload.new('score[meta_doc]', 'path-to-file') 2 | # PostMultipart.to('/path', {param1: 'foo'}, upload) 3 | module OpenKit 4 | module Request 5 | 6 | 7 | class PostMultipart < Base 8 | attr_reader :upload 9 | 10 | def self.to(path, req_params, upload) 11 | new(path, req_params, upload).perform 12 | end 13 | 14 | def initialize(path, req_params, upload) 15 | super :post, PostMultipartDelegate.new(path, req_params, upload) 16 | @upload = upload 17 | end 18 | 19 | def perform 20 | response = super 21 | @upload.close 22 | response 23 | end 24 | end 25 | 26 | 27 | class PostMultipartDelegate < BaseDelegate 28 | 29 | def initialize(path, req_params, upload) 30 | super(path) 31 | @req_params = req_params 32 | @upload = upload 33 | end 34 | 35 | def net_request 36 | up_io = UploadIO.new(@upload.file, "application/octet-stream", "upload") 37 | flat_params = flatten_params(@req_params) 38 | req = Net::HTTP::Post::Multipart.new(uri.request_uri, flat_params.merge(@upload.param_name => up_io)) 39 | req['Accept'] = "application/json" 40 | req 41 | end 42 | 43 | def flatten_params(parameters) 44 | flattened = {} 45 | flat_names(parameters, '') do |name,v| 46 | flattened[name] = v 47 | end 48 | flattened 49 | end 50 | 51 | def flat_names(parameters, running = '', &block) 52 | parameters.each do |k,v| 53 | name = (running.length == 0) ? k.to_s : running + "[#{k}]" 54 | if v.is_a?(Hash) 55 | flat_names(v, name, &block) 56 | else 57 | yield name, v 58 | end 59 | end 60 | end 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /clients/ruby/lib/openkit/request/put.rb: -------------------------------------------------------------------------------- 1 | # Put.to('/path', {param1: 'foo'}) 2 | module OpenKit 3 | module Request 4 | 5 | class Put < Base 6 | 7 | def self.to(path, req_params) 8 | new(path, req_params).perform 9 | end 10 | 11 | def initialize(path, req_params) 12 | super :put, PutDelegate.new(path, req_params) 13 | end 14 | end 15 | 16 | 17 | class PutDelegate < BaseDelegate 18 | 19 | def initialize(path, req_params) 20 | super(path) 21 | @req_params = req_params 22 | end 23 | 24 | def net_request 25 | req = Net::HTTP::Put.new(uri.request_uri) 26 | req.set_body_internal(@req_params.to_json) 27 | req['Content-Type'] = "application/json; charset=utf-8" 28 | req['Accept'] = "application/json" 29 | req 30 | end 31 | end 32 | end 33 | end -------------------------------------------------------------------------------- /clients/ruby/lib/openkit/request/upload.rb: -------------------------------------------------------------------------------- 1 | module OpenKit 2 | module Request 3 | 4 | class Upload 5 | attr_accessor :param_name, :filepath 6 | 7 | def initialize(param_name, filepath) 8 | @param_name = param_name 9 | @filepath = filepath 10 | end 11 | 12 | def file 13 | @file ||= File.open(@filepath) 14 | end 15 | 16 | def close 17 | @file.close if @file # Use ivar directly, not the #file method. 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /clients/ruby/lib/openkit/version.rb: -------------------------------------------------------------------------------- 1 | module Openkit 2 | VERSION = "0.0.2" 3 | end 4 | -------------------------------------------------------------------------------- /clients/ruby/openkit.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'openkit/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "openkit" 8 | spec.version = Openkit::VERSION 9 | spec.authors = ["Lou Zell"] 10 | spec.email = ["lou@openkit.io"] 11 | spec.description = %q{List leaderboards, post scores, etc.} 12 | spec.summary = %q{Client for OpenKit's gaming backend} 13 | spec.homepage = "https://github.com/OpenKit/openkit-server/tree/development/clients/ruby" 14 | spec.license = "MIT" 15 | spec.files = %w[ 16 | Gemfile 17 | LICENSE.txt 18 | README.md 19 | Rakefile 20 | lib/openkit.rb 21 | lib/openkit/request/base.rb 22 | lib/openkit/request/base_delegate.rb 23 | lib/openkit/request/delete.rb 24 | lib/openkit/request/get.rb 25 | lib/openkit/request/post.rb 26 | lib/openkit/request/post_multipart.rb 27 | lib/openkit/request/put.rb 28 | lib/openkit/request/upload.rb 29 | lib/openkit/request.rb 30 | lib/openkit/version.rb 31 | test/api/score_api_test.rb 32 | test/api/user_api_test.rb 33 | test/test_helper.rb 34 | openkit.gemspec 35 | ] 36 | spec.executables = [] 37 | spec.test_files = spec.files.grep(%r{^(test)/}) 38 | spec.require_paths = ["lib"] 39 | 40 | spec.add_development_dependency "bundler", "~> 1.3" 41 | spec.add_development_dependency "rake", "~> 10.1" 42 | spec.add_development_dependency "minitest", "~> 4.7" 43 | spec.add_development_dependency "turn", "~> 0" 44 | 45 | spec.add_dependency 'multipart-post', "~> 2.0" 46 | end 47 | -------------------------------------------------------------------------------- /clients/ruby/test/api/score_api_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper.rb' 2 | 3 | class ScoreApiTest < ApiTest 4 | def setup 5 | super 6 | @leaderboard_id = 831 7 | @user_id = 237492 8 | end 9 | 10 | def test_create 11 | custom_id = random_alphanumeric(7) 12 | nick = "guest-#{custom_id}" 13 | 14 | request = Post.new '/v1/scores', {score: {user_id: @user_id, leaderboard_id: @leaderboard_id, value: 100}} 15 | response = request.perform 16 | assert response.code =~ /^20\d/, "Got a return code of #{response.code}" 17 | 18 | score = JSON.parse(response.body) 19 | assert score['id'] 20 | end 21 | end 22 | 23 | -------------------------------------------------------------------------------- /clients/ruby/test/api/user_api_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper.rb' 2 | 3 | class UserApiTest < ApiTest 4 | def test_create 5 | custom_id = random_alphanumeric(7) 6 | nick = "guest-#{custom_id}" 7 | 8 | request = Post.new '/v1/users', {user: {custom_id: custom_id, nick: nick}} 9 | response = request.perform 10 | assert response.code =~ /^20\d/ 11 | 12 | user = JSON.parse(response.body) 13 | assert user['id'] 14 | end 15 | end 16 | 17 | -------------------------------------------------------------------------------- /clients/ruby/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'openkit' 2 | gem "minitest", '~>4.7' 3 | require 'minitest/autorun' 4 | require 'turn' 5 | #require 'debugger' 6 | 7 | class ApiTest < MiniTest::Unit::TestCase 8 | include OpenKit::Request 9 | 10 | def setup 11 | OpenKit::Config.skip_https = true 12 | OpenKit::Config.app_key = '9c7FMNznXbQC4Pr4FHi5' 13 | OpenKit::Config.secret_key = 'o2HdzSZg99jdmP4oi0LdiJwFPYG06gXvCGqNHeXG' 14 | end 15 | 16 | def random_alphanumeric(n) 17 | Array.new(n){[*'0'..'9', *'a'..'z', *'A'..'Z'].sample}.join 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /dashboard/Capfile: -------------------------------------------------------------------------------- 1 | require 'capistrano/setup' 2 | require 'capistrano/deploy' 3 | require 'capistrano/bundler' 4 | require 'capistrano/rails/assets' 5 | require 'capistrano/rails/migrations' 6 | Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r } 7 | 8 | require_relative 'lib/capistrano/git_strategy' 9 | require_relative 'lib/capistrano/log_invocations' 10 | 11 | LogInvocations.enable 12 | -------------------------------------------------------------------------------- /dashboard/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rails', '~> 4.0' 4 | gem 'sqlite3' 5 | gem 'protected_attributes' 6 | 7 | # Bundle edge Rails instead: 8 | # gem 'rails', :git => 'git://github.com/rails/rails.git' 9 | 10 | gem 'mysql2', '0.3.14' 11 | gem 'authlogic', :git => 'git://github.com/binarylogic/authlogic.git', :ref => 'abc0997' 12 | gem 'paperclip', '~>3.3' 13 | gem 'delayed_job', '~>4.0' 14 | gem 'delayed_job_active_record', '~>4.0' 15 | gem 'redis', '~>3.0' 16 | gem 'hiredis', '~>0.4' 17 | gem 'daemons', '~>1.1' 18 | gem 'json', '~>1.7' 19 | gem 'aws-sdk', '~>1.9' 20 | gem 'oauth', '~>0.4' 21 | gem 'acts-as-taggable-on', '~>2.4' 22 | gem 'unf', '~>0.1' 23 | gem 'mustache', '~>0.99' 24 | gem 'highline' 25 | gem 'colorize' 26 | 27 | group :development do 28 | gem 'thin' 29 | gem 'fog' 30 | gem 'wirble' 31 | gem 'what_methods' 32 | # gem 'tracer_bullet' 33 | gem 'quiet_assets' 34 | gem 'capistrano', '~> 3.1', require: false 35 | gem 'capistrano-rails', '~> 1.1', require: false 36 | end 37 | 38 | group :test do 39 | gem 'mocha', :require => false 40 | gem 'openkit', '~> 0.0.2' #, :path => '../clients/ruby' 41 | gem 'turn' 42 | gem 'factory_girl' 43 | end 44 | 45 | group :development, :test do 46 | gem 'byebug' 47 | end 48 | 49 | gem 'sass-rails', '~> 4.0.0' 50 | gem 'coffee-rails', '~> 4.0.0' 51 | gem 'uglifier', '>= 1.3.0' 52 | gem 'jquery-rails' 53 | 54 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 55 | gem 'therubyracer', :platforms => :ruby 56 | 57 | # Still needed? 58 | #gem 'turbo-sprockets-rails3' 59 | 60 | # To use ActiveModel has_secure_password 61 | # gem 'bcrypt-ruby', '~> 3.0.0' 62 | 63 | # To use Jbuilder templates for JSON 64 | # gem 'jbuilder' 65 | 66 | # Use unicorn as the app server 67 | gem 'unicorn' 68 | 69 | # To use debugger 70 | # gem 'debugger' 71 | -------------------------------------------------------------------------------- /dashboard/README.md: -------------------------------------------------------------------------------- 1 | openkit-server 2 | =============== 3 | 4 | After downloading build required gems with: 5 | ``` 6 | $ bundle install 7 | ``` 8 | 9 | 10 | Start delayed _ job locally with: 11 | ``` 12 | $ rake jobs:work 13 | ``` 14 | 15 | See a list of all rake-able jobs: 16 | ``` 17 | $ bin/rake -T 18 | ``` 19 | 20 | Start server with: 21 | ``` 22 | $ bin/rails server 23 | ``` 24 | 25 | To start the server using a unix socket: 26 | ``` 27 | $ bundle exec thin -V start --socket /tmp/thin.sock 28 | ``` 29 | 30 | License 31 | ------- 32 | OpenKit Server 33 | Copyright (C) 2013 OpenKit 34 | 35 | This program is free software: you can redistribute it and/or modify 36 | it under the terms of the GNU Affero General Public License as 37 | published by the Free Software Foundation, either version 3 of the 38 | License, or (at your option) any later version. 39 | 40 | This program is distributed in the hope that it will be useful, 41 | but WITHOUT ANY WARRANTY; without even the implied warranty of 42 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 43 | GNU Affero General Public License for more details. 44 | 45 | A copy of the GNU Affero General Public License is included in this 46 | repository at AGPL-License.txt. 47 | -------------------------------------------------------------------------------- /dashboard/Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | OKDashboard::Application.load_tasks 8 | -------------------------------------------------------------------------------- /dashboard/app/assets/fonts/Elusive-Icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/fonts/Elusive-Icons.eot -------------------------------------------------------------------------------- /dashboard/app/assets/fonts/Elusive-Icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/fonts/Elusive-Icons.ttf -------------------------------------------------------------------------------- /dashboard/app/assets/fonts/Elusive-Icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/fonts/Elusive-Icons.woff -------------------------------------------------------------------------------- /dashboard/app/assets/images/achievement_dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/achievement_dash.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/android_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/android_icon.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/app_icon.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/bg.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/cloud_dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/cloud_dash.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/cloud_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/cloud_icon.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/invites_dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/invites_dash.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/ios_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/ios_icon.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/leaderboard_dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/leaderboard_dash.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/login_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/login_logo.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/logo.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/multiplayer_dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/multiplayer_dash.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/photon-server-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/photon-server-logo.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/photon-slide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/photon-slide.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/push_dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/push_dash.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/rails.png -------------------------------------------------------------------------------- /dashboard/app/assets/images/unity_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/assets/images/unity_icon.png -------------------------------------------------------------------------------- /dashboard/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require_tree . 16 | 17 | -------------------------------------------------------------------------------- /dashboard/app/assets/javascripts/custom.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | 3 | $("#flash i").click(function(){ 4 | $(this).parent().slideUp(); 5 | }) 6 | 7 | // setTimeout(function() { 8 | // $('#flash').fadeOut(); 9 | // }, 2500); 10 | 11 | $(".account").click(function(){ 12 | var X=$(this).attr('id'); 13 | if(X==1){ 14 | $(".subnav").hide(); 15 | $(this).attr('id', '0'); 16 | $(this).removeClass('active'); 17 | } 18 | else{ 19 | $(".subnav").show(); 20 | $(this).attr('id', '1'); 21 | $(this).addClass('active'); 22 | } 23 | }); 24 | 25 | //Mouse click on sub menu 26 | $(".subnav").mouseup(function(){ 27 | return false 28 | }); 29 | 30 | //Mouse click on my account link 31 | $(".account").mouseup(function(){ 32 | return false 33 | }); 34 | 35 | 36 | //Document Click 37 | // $(document).mouseup(function(){ 38 | // $(".subnav").hide(); 39 | // $(".account").attr('id', ''); 40 | // $(".account").removeClass('active'); 41 | // }); 42 | 43 | // $(".md-trigger").click(function(){ 44 | // $(".md-modal").addClass("md-show"); 45 | // return false; 46 | // }); 47 | 48 | // $(".md-close").click(function(){ 49 | // $(".md-modal").removeClass("md-show"); 50 | // return false; 51 | // }); 52 | }); 53 | -------------------------------------------------------------------------------- /dashboard/app/assets/javascripts/modalEffects.js: -------------------------------------------------------------------------------- 1 | /** 2 | * modalEffects.js v1.0.0 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2013, Codrops 9 | * http://www.codrops.com 10 | */ 11 | var ModalEffects = (function() { 12 | 13 | function init() { 14 | 15 | var overlay = document.querySelector( '.md-overlay' ); 16 | 17 | [].slice.call( document.querySelectorAll( '.md-trigger' ) ).forEach( function( el, i ) { 18 | 19 | var modal = document.querySelector( '#' + el.getAttribute( 'data-modal' ) ), 20 | close = modal.querySelector( '.md-close' ); 21 | 22 | function removeModal( hasPerspective ) { 23 | classie.remove( modal, 'md-show' ); 24 | 25 | if( hasPerspective ) { 26 | classie.remove( document.documentElement, 'md-perspective' ); 27 | } 28 | } 29 | 30 | function removeModalHandler() { 31 | removeModal( classie.has( el, 'md-setperspective' ) ); 32 | } 33 | 34 | el.addEventListener( 'click', function( ev ) { 35 | classie.add( modal, 'md-show' ); 36 | overlay.removeEventListener( 'click', removeModalHandler ); 37 | overlay.addEventListener( 'click', removeModalHandler ); 38 | 39 | if( classie.has( el, 'md-setperspective' ) ) { 40 | setTimeout( function() { 41 | classie.add( document.documentElement, 'md-perspective' ); 42 | }, 25 ); 43 | } 44 | }); 45 | 46 | close.addEventListener( 'click', function( ev ) { 47 | ev.stopPropagation(); 48 | removeModalHandler(); 49 | }); 50 | 51 | } ); 52 | 53 | } 54 | 55 | init(); 56 | 57 | })(); -------------------------------------------------------------------------------- /dashboard/app/assets/stylesheets/application.css.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | */ 13 | 14 | @import "reset.css.scss"; 15 | @import "mixins.css.scss"; 16 | @import "layout.css.scss"; 17 | @import "general.css.scss"; 18 | @import "component.css.scss"; 19 | @import "elusive-webfont.css.scss"; 20 | -------------------------------------------------------------------------------- /dashboard/app/assets/stylesheets/reset.css.scss: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, p, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, font, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | dl, dt, dd, ol, ul, li, 12 | fieldset, form, label, legend, 13 | table, caption, tbody, tfoot, thead, tr, th, td { 14 | margin: 0; 15 | padding: 0; 16 | border: 0; 17 | outline: 0; 18 | font-weight: inherit; 19 | font-style: inherit; 20 | font-size: 100%; 21 | font-family: inherit; 22 | vertical-align: baseline; 23 | } 24 | /* remember to define focus styles! */ 25 | :focus {outline: 0;} 26 | /* remind IE to use a pointer on links */ 27 | a {cursor:pointer;} 28 | /* remove safari input highlighting */ 29 | input {outline: none;} 30 | body {line-height: 1;color: black;background: white;} 31 | ol, ul {list-style: none;} 32 | /* tables still need 'cellspacing="0"' in the markup */ 33 | table {border-collapse: separate;border-spacing: 0;} 34 | caption, th, td {text-align: left;font-weight: normal;} 35 | blockquote:before, blockquote:after, q:before, q:after {content: "";} 36 | blockquote, q {quotes: "" "";} 37 | -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v08/achievement_scores_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V08 2 | class AchievementScoresController < ApplicationController 3 | before_filter :set_achievement 4 | 5 | def create 6 | err_message = nil 7 | user_id = params[:achievement_score].delete(:user_id) 8 | err_message = "Please pass a user_id with your achievement_score." if user_id.blank? 9 | 10 | if !err_message 11 | user = user_id && authorized_app.users.find_by_id(user_id.to_i + 100000) 12 | end 13 | 14 | err_message = "User with that ID is not subscribed to this app." if !user 15 | if !err_message 16 | @achievement_score = @achievement.achievement_scores.build(params[:achievement_score]) 17 | @achievement_score.user = user 18 | if !@achievement_score.save 19 | err_message = "#{@achievement_score.errors.full_messages.join(", ")}" 20 | end 21 | end 22 | 23 | if err_message 24 | render status: :bad_request, json: {message: err_message} 25 | else 26 | j = @achievement_score.as_json 27 | j['user_id'] -= 100000 28 | render json: j 29 | end 30 | end 31 | 32 | private 33 | def set_achievement 34 | l_id1 = params[:achievement_score] && params[:achievement_score].delete(:achievement_id) 35 | l_id2 = params.delete(:achievement_id) 36 | if(achievement_id = l_id1 || l_id2) 37 | @achievement = authorized_app.achievements.find_by_id(achievement_id.to_i) 38 | end 39 | 40 | unless @achievement 41 | render status: :forbidden, json: {message: "Pass a achievement_id that belongs to the app associated with app_key"} 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v08/achievements_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V08 2 | class AchievementsController < ApplicationController 3 | 4 | def index 5 | @achievements = authorized_app.achievements 6 | user_id = params[:user_id] && (params[:user_id].to_i + 100000) 7 | render json: @achievements.map {|x| x.api_fields(request_base_uri, false, user_id)} 8 | end 9 | 10 | def create 11 | @achievement = authorized_app.achievements.new(params[:achievement]) 12 | if @achievement.save 13 | render json: @achievement.api_fields(request_base_uri, false), status: :created 14 | else 15 | render json: @achievement.errors, status: :unprocessable_entity 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v08/application_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V08 2 | class ApplicationController < ActionController::Base 3 | layout false 4 | respond_to :json 5 | before_filter :require_authorized_app 6 | 7 | private 8 | def authorized_app 9 | return @authorized_app if defined?(@authorized_app) 10 | @authorized_app = request.env[:authorized_app] 11 | end 12 | 13 | def require_authorized_app 14 | unless authorized_app 15 | render :status => :forbidden, :json => { message: "Please check your app_key and secret_key." } 16 | end 17 | end 18 | 19 | def content_type_json? 20 | request.content_type == "application/json" 21 | end 22 | 23 | def accepts_json? 24 | request.accepts.include?("application/json") || request.accepts.include?("*/*") 25 | end 26 | 27 | def request_base_uri 28 | request.protocol + request.host_with_port 29 | end 30 | end 31 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v08/apps_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V08 2 | class AppsController < ApplicationController 3 | 4 | def purge_test_data 5 | test_app = App.find_by(app_key: "end_to_end_test") 6 | if test_app 7 | test_app.leaderboards.destroy_all 8 | test_app.achievements.destroy_all 9 | render json: %|{"ok":true}| 10 | else 11 | render json: %|{"ok":false}| 12 | end 13 | end 14 | end 15 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v08/leaderboards_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V08 2 | class LeaderboardsController < ApplicationController 3 | 4 | def index 5 | if params[:tag] 6 | @leaderboards = authorized_app.leaderboards.tagged_with(params[:tag].to_s).order(:priority) 7 | else 8 | @leaderboards = authorized_app.leaderboards.order(:priority) 9 | end 10 | render json: @leaderboards.map {|x| x.api_fields(request_base_uri, false)} 11 | end 12 | 13 | def show 14 | err_message = nil 15 | lid = params[:id] && params[:id].to_i 16 | err_message = "You must pass a leaderboard id" unless lid 17 | 18 | if !err_message 19 | @leaderboard = authorized_app.leaderboards.find_by_id(lid) 20 | err_message = "Your app does not have a leaderboard with id: #{lid}" unless @leaderboard 21 | end 22 | 23 | if !err_message 24 | render json: @leaderboard.api_fields(request_base_uri, false) 25 | else 26 | render status: :bad_request, json: {message: err_message} 27 | end 28 | end 29 | 30 | def create 31 | @leaderboard = authorized_app.leaderboards.new(params[:leaderboard]) 32 | if @leaderboard.save 33 | render json: @leaderboard.api_fields(request_base_uri, false), status: :created 34 | else 35 | render json: @leaderboard.errors, status: :unprocessable_entity 36 | end 37 | end 38 | end 39 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v08/users_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V08 2 | class UsersController < ApplicationController 3 | 4 | def create 5 | err_message = nil 6 | 7 | @user = authorized_app.find_or_create_subscribed_user(params[:user]) 8 | err_message = "Could not create that user." if @user.nil? 9 | err_message = "Couldn't subscribe user because:#{@user.errors.full_messages[0]}" if @user.errors.count != 0 10 | 11 | if !err_message 12 | u = @user.as_json 13 | if !u.blank? 14 | u['fb_id'] = u['fb_id'].to_i if u['fb_id'] 15 | u['google_id'] = u['google_id'].to_i if u['google_id'] 16 | u['twitter_id'] = u['twitter_id'].to_i if u['twitter_id'] 17 | u['custom_id'] = u['custom_id'].to_i if u['custom_id'] 18 | 19 | u['id'] -= 100000 20 | end 21 | render json: u, status: :created 22 | else 23 | render status: :bad_request, json: {message: err_message} 24 | end 25 | end 26 | 27 | def update 28 | @user = authorized_app.developer.users.find_by_id(params[:id].to_i + 100000) 29 | if @user.nil? 30 | render status: :forbidden, json: {message: "User with that id does not belong to you"} 31 | else 32 | params[:user].delete :id 33 | params[:user].delete :developer_id 34 | if @user.update_attributes(params[:user]) 35 | u = @user.as_json 36 | if !u.blank? 37 | u['fb_id'] = u['fb_id'].to_i if u['fb_id'] 38 | u['google_id'] = u['google_id'].to_i if u['google_id'] 39 | u['twitter_id'] = u['twitter_id'].to_i if u['twitter_id'] 40 | u['custom_id'] = u['custom_id'].to_i if u['custom_id'] 41 | 42 | u['id'] -= 100000 43 | end 44 | render status: :ok, json: u 45 | else 46 | render status: :unprocessable_entity, json: {message: @user.errors.full_messages.join(', ')} 47 | end 48 | end 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v09/achievement_scores_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V09 2 | class AchievementScoresController < ApplicationController 3 | before_filter :set_achievement 4 | 5 | def create 6 | err_message = nil 7 | user_id = params[:achievement_score].delete(:user_id) 8 | err_message = "Please pass a user_id with your achievement_score." if user_id.blank? 9 | 10 | if !err_message 11 | user = user_id && authorized_app.users.find_by_id(user_id.to_i) 12 | end 13 | 14 | err_message = "User with that ID is not subscribed to this app." if !user 15 | if !err_message 16 | @achievement_score = @achievement.achievement_scores.build(params[:achievement_score]) 17 | @achievement_score.user = user 18 | if !@achievement_score.save 19 | err_message = "#{@achievement_score.errors.full_messages.join(", ")}" 20 | end 21 | end 22 | 23 | if err_message 24 | render status: :bad_request, json: {message: err_message} 25 | else 26 | render json: @achievement_score 27 | end 28 | end 29 | 30 | private 31 | def set_achievement 32 | l_id1 = params[:achievement_score] && params[:achievement_score].delete(:achievement_id) 33 | l_id2 = params.delete(:achievement_id) 34 | if(achievement_id = l_id1 || l_id2) 35 | @achievement = authorized_app.achievements.find_by_id(achievement_id.to_i) 36 | end 37 | 38 | unless @achievement 39 | render status: :forbidden, json: {message: "Pass a achievement_id that belongs to the app associated with app_key"} 40 | end 41 | end 42 | end 43 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v09/achievements_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V09 2 | class AchievementsController < ApplicationController 3 | 4 | def index 5 | @achievements = authorized_app.achievements 6 | user_id = params[:user_id] && params[:user_id].to_i 7 | render json: @achievements.map {|x| x.api_fields(request_base_uri, false, user_id)} 8 | end 9 | 10 | def create 11 | @achievement = authorized_app.achievements.new(params[:achievement]) 12 | if @achievement.save 13 | render json: @achievement.api_fields(request_base_uri, false), status: :created 14 | else 15 | render json: @achievement.errors, status: :unprocessable_entity 16 | end 17 | end 18 | end 19 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v09/application_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V09 2 | class ApplicationController < ActionController::Base 3 | layout false 4 | respond_to :json 5 | before_filter :require_authorized_app 6 | 7 | private 8 | def authorized_app 9 | return @authorized_app if defined?(@authorized_app) 10 | @authorized_app = request.env[:authorized_app] 11 | end 12 | 13 | def require_authorized_app 14 | unless authorized_app 15 | render :status => :forbidden, :json => { message: "Please check your app_key and secret_key." } 16 | end 17 | end 18 | 19 | def content_type_json? 20 | request.content_type == "application/json" 21 | end 22 | 23 | def accepts_json? 24 | request.accepts.include?("application/json") || request.accepts.include?("*/*") 25 | end 26 | 27 | def request_base_uri 28 | request.protocol + request.host_with_port 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v09/apps_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V09 2 | class AppsController < ApplicationController 3 | 4 | def purge_test_data 5 | test_app = App.find_by(app_key: "end_to_end_test") 6 | if test_app 7 | test_app.leaderboards.destroy_all 8 | test_app.achievements.destroy_all 9 | render json: %|{"ok":true}| 10 | else 11 | render json: %|{"ok":false}| 12 | end 13 | end 14 | end 15 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v09/leaderboards_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V09 2 | class LeaderboardsController < ApplicationController 3 | 4 | def index 5 | tag = params[:tag] && params[:tag].to_s 6 | tag = "v1" if tag.blank? 7 | if tag 8 | @leaderboards = authorized_app.leaderboards.tagged_with(tag).order(:priority) 9 | else 10 | @leaderboards = authorized_app.leaderboards.order(:priority) 11 | end 12 | render json: @leaderboards.map {|x| x.api_fields(request_base_uri, false)} 13 | end 14 | 15 | def show 16 | err_message = nil 17 | lid = params[:id] && params[:id].to_i 18 | err_message = "You must pass a leaderboard id" unless lid 19 | 20 | if !err_message 21 | @leaderboard = authorized_app.leaderboards.find_by_id(lid) 22 | err_message = "Your app does not have a leaderboard with id: #{lid}" unless @leaderboard 23 | end 24 | 25 | if !err_message 26 | render json: @leaderboard.api_fields(request_base_uri, false) 27 | else 28 | render status: :bad_request, json: {message: err_message} 29 | end 30 | end 31 | 32 | def create 33 | @leaderboard = authorized_app.leaderboards.new(params[:leaderboard]) 34 | if @leaderboard.save 35 | render json: @leaderboard.api_fields(request_base_uri, false), status: :created 36 | else 37 | render json: @leaderboard.errors, status: :unprocessable_entity 38 | end 39 | end 40 | end 41 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v09/scores_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V09 2 | class ScoresController < ApplicationController 3 | before_filter :set_leaderboard 4 | 5 | def show 6 | @score = @leaderboard.scores.find(params[:id].to_i) 7 | render json: @score 8 | end 9 | 10 | def create 11 | err_message = nil 12 | user_id = params[:score].delete(:user_id) 13 | err_message = "Please pass a user_id with your score." if user_id.blank? 14 | 15 | if !err_message 16 | user = user_id && authorized_app.users.find_by_id(user_id.to_i) 17 | end 18 | 19 | err_message = "User with that ID is not subscribed to this app." if !user 20 | if !err_message 21 | value = params[:score].delete(:value) 22 | @score = @leaderboard.scores.build(params[:score]) 23 | @score.value = value 24 | @score.user = user 25 | if !@score.save 26 | err_message = "#{@score.errors.full_messages.join(", ")}" 27 | end 28 | end 29 | 30 | if err_message 31 | render status: :bad_request, json: {message: err_message} 32 | else 33 | j = @score.as_json(:only => BaseScore::DEFAULT_JSON_PROPS, :methods => [:value]) 34 | if !j.blank? 35 | if j[:user] 36 | j[:user]['fb_id'] = j[:user]['fb_id'].to_i if j[:user]['fb_id'] 37 | j[:user]['twitter_id'] = j[:user]['twitter_id'].to_i if j[:user]['twitter_id'] 38 | j[:user]['custom_id'] = j[:user]['custom_id'].to_i if j[:user]['custom_id'] 39 | end 40 | end 41 | render json: j 42 | end 43 | end 44 | 45 | private 46 | def set_leaderboard 47 | l_id1 = params[:score] && params[:score].delete(:leaderboard_id) 48 | l_id2 = params.delete(:leaderboard_id) 49 | if(leaderboard_id = l_id1 || l_id2) 50 | @leaderboard = authorized_app.leaderboards.find_by_id(leaderboard_id.to_i) 51 | end 52 | 53 | unless @leaderboard 54 | render status: :forbidden, json: {message: "Pass a leaderboard_id that belongs to the app associated with app_key"} 55 | end 56 | end 57 | end 58 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v09/users_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V09 2 | class UsersController < ApplicationController 3 | 4 | def create 5 | err_message = nil 6 | 7 | @user = authorized_app.find_or_create_subscribed_user(params[:user]) 8 | err_message = "Could not create that user." if @user.nil? 9 | err_message = "Couldn't subscribe user because:#{@user.errors.full_messages[0]}" if @user.errors.count != 0 10 | 11 | if !err_message 12 | u = @user.as_json 13 | if !u.blank? 14 | u['fb_id'] = u['fb_id'].to_i if u['fb_id'] 15 | u['twitter_id'] = u['twitter_id'].to_i if u['twitter_id'] 16 | u['custom_id'] = u['custom_id'].to_i if u['custom_id'] 17 | end 18 | render json: u, status: :created 19 | else 20 | render status: :bad_request, json: {message: err_message} 21 | end 22 | end 23 | 24 | def update 25 | @user = authorized_app.developer.users.find_by_id(params[:id].to_i) 26 | if @user.nil? 27 | render status: :forbidden, json: {message: "User with that id does not belong to you"} 28 | else 29 | params[:user].delete :id 30 | params[:user].delete :developer_id 31 | if @user.update_attributes(params[:user]) 32 | u = @user.as_json 33 | if !u.blank? 34 | u['fb_id'] = u['fb_id'].to_i if u['fb_id'] 35 | u['twitter_id'] = u['twitter_id'].to_i if u['twitter_id'] 36 | u['custom_id'] = u['custom_id'].to_i if u['custom_id'] 37 | end 38 | render status: :ok, json: u 39 | else 40 | render status: :unprocessable_entity, json: {message: @user.errors.full_messages.join(', ')} 41 | end 42 | end 43 | end 44 | end 45 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v1/achievement_scores_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V1 2 | class AchievementScoresController < ApplicationController 3 | before_filter :set_achievement 4 | 5 | def create 6 | err_message = nil 7 | err_code = nil 8 | user_id = params[:achievement_score].delete(:user_id) 9 | if user_id.blank? 10 | err_message = "Please pass a user_id with your achievement_score." 11 | err_code = :bad_request 12 | end 13 | 14 | if !err_message 15 | user = user_id && authorized_app.users.find_by_id(user_id.to_i) 16 | if !user 17 | err_message = "User with that ID is not subscribed to this app." 18 | err_code = 410 19 | end 20 | end 21 | 22 | if !err_message 23 | @achievement_score = @achievement.send(achievement_scores_association).build(params[:achievement_score]) 24 | @achievement_score.user = user 25 | if !@achievement_score.save 26 | err_message = "#{@achievement_score.errors.full_messages.join(", ")}" 27 | err_code = :bad_request 28 | end 29 | end 30 | 31 | if err_message 32 | render status: err_code, json: {message: err_message} 33 | else 34 | render json: @achievement_score 35 | end 36 | end 37 | 38 | private 39 | def set_achievement 40 | l_id1 = params[:achievement_score] && params[:achievement_score].delete(:achievement_id) 41 | l_id2 = params.delete(:achievement_id) 42 | if(achievement_id = l_id1 || l_id2) 43 | @achievement = authorized_app.achievements.find_by_id(achievement_id.to_i) 44 | end 45 | 46 | unless @achievement 47 | render status: :forbidden, json: {message: "Pass a achievement_id that belongs to the app associated with app_key"} 48 | end 49 | end 50 | 51 | def achievement_scores_association 52 | in_sandbox? ? :sandbox_achievement_scores : :achievement_scores 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v1/achievements_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V1 2 | class AchievementsController < ApplicationController 3 | 4 | def index 5 | @achievements = authorized_app.achievements 6 | user_id = params[:user_id] && params[:user_id].to_i 7 | render json: @achievements.map {|x| x.api_fields(request_base_uri, in_sandbox?, user_id)} 8 | end 9 | 10 | def create 11 | @achievement = authorized_app.achievements.new(params[:achievement]) 12 | if @achievement.save 13 | render json: @achievement.api_fields(request_base_uri, in_sandbox?), status: :created 14 | else 15 | render json: @achievement.errors, status: :unprocessable_entity 16 | end 17 | end 18 | end 19 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v1/application_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V1 2 | class ApplicationController < ActionController::Base 3 | layout false 4 | respond_to :json 5 | before_filter :require_authorized_app 6 | 7 | private 8 | def authorized_app 9 | return @authorized_app if defined?(@authorized_app) 10 | @authorized_app = request.env[:authorized_app] 11 | end 12 | 13 | def require_authorized_app 14 | unless authorized_app 15 | render :status => 401, :json => { message: "Please check your app_key and secret_key." } 16 | end 17 | end 18 | 19 | def content_type_json? 20 | request.content_type == "application/json" 21 | end 22 | 23 | def accepts_json? 24 | request.accepts.include?("application/json") || request.accepts.include?("*/*") 25 | end 26 | 27 | def request_base_uri 28 | request.protocol + request.host_with_port 29 | end 30 | 31 | def in_sandbox? 32 | !!request.subdomain.match(/^(?:beta-)?sandbox$/) 33 | end 34 | 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v1/apps_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V1 2 | class AppsController < ApplicationController 3 | 4 | def purge_test_data 5 | test_app = App.find_by(app_key: "end_to_end_test") 6 | if test_app 7 | test_app.leaderboards.destroy_all 8 | test_app.achievements.destroy_all 9 | test_app.developer.users.destroy_all 10 | head :ok 11 | else 12 | render json: {message: "no test app on this endpoint."} 13 | end 14 | end 15 | end 16 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v1/best_scores_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V1 2 | class BestScoresController < ApplicationController 3 | before_filter :set_leaderboard 4 | 5 | # Note: 6 | # The overriden method User#as_json does not get called when ':include => :user' 7 | # is passed to Score#as_json. 8 | def index 9 | x = params.delete(:page_num) 10 | y = params.delete(:num_per_page) 11 | @scores = score_class.bests_1_0(@leaderboard.id, {page_num: x, num_per_page: y}) 12 | ActiveRecord::Associations::Preloader.new(@scores, [:user]).run 13 | render json: @scores 14 | end 15 | 16 | def user 17 | @score = score_class.best_1_0(@leaderboard.id, params[:user_id]) 18 | ActiveRecord::Associations::Preloader.new(@score, [:user]).run 19 | render json: @score 20 | end 21 | 22 | def social 23 | @scores = params[:fb_friends] && score_class.social(authorized_app, @leaderboard, params[:fb_friends]) || [] 24 | render json: @scores 25 | end 26 | 27 | private 28 | def set_leaderboard 29 | @leaderboard = authorized_app.leaderboards.find_by_id(params.delete(:leaderboard_id)) 30 | unless @leaderboard 31 | render status: :forbidden, json: {message: "Pass a leaderboard_id that belongs to the app associated with app_key"} 32 | end 33 | end 34 | 35 | def score_class 36 | @score_class ||= in_sandbox? ? SandboxScore : Score 37 | end 38 | end 39 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v1/challenges_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V1 2 | class ChallengesController < ApplicationController 3 | before_filter :set_leaderboard 4 | 5 | # POST to /leaderboards/:leaderboard_id/challenges with params: 6 | # { 7 | # sender_id: 8 | # receiver_ids: [x, y, z] 9 | # } 10 | # 11 | # This method stuffs the sender_id, receiver_id, and leaderboard_id into push 12 | # queue to be handled later. Push queues are keyed by developer_id:push_queue. 13 | def create 14 | sender_id = params[:sender_id] && params[:sender_id].to_i 15 | receiver_ids = params[:receiver_ids] && params[:receiver_ids].is_a?(Array) && params[:receiver_ids].map(&:to_i) 16 | 17 | challenge = Challenge.new( 18 | sender_id: sender_id, 19 | receiver_ids: receiver_ids, 20 | leaderboard: @leaderboard, 21 | app: authorized_app, 22 | sandbox: in_sandbox? 23 | ) 24 | 25 | if challenge.save 26 | head :ok 27 | else 28 | render status: :bad_request, json: {message: challenge.errors.join(", ")} 29 | end 30 | end 31 | 32 | private 33 | def set_leaderboard 34 | @leaderboard = authorized_app && authorized_app.leaderboards.find_by_id(params[:leaderboard_id].to_i) 35 | unless @leaderboard 36 | render :status => :forbidden, :json => { message: "You do not have access to this leaderboard." } 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v1/client_sessions_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V1 2 | class ClientSessionsController < ApplicationController 3 | 4 | def create 5 | @client_session = client_session_class.new(params[:client_session]) 6 | @client_session.app_id = authorized_app.id 7 | # Really we could just be logging these out, as none of the fields 8 | # in the client_sessions db are indexed. The only special thing we 9 | # handle is adding push tokens to a users list, if we have that info. 10 | if @client_session.ok_id && @client_session.push_token 11 | if user = authorized_app.developer.users.find_by_id(@client_session.ok_id.to_i) 12 | token_class.find_or_create_by_user_id_and_app_id_and_apns_token(user.id, authorized_app.id, @client_session.push_token) 13 | end 14 | end 15 | 16 | if @client_session.save 17 | head :ok 18 | else 19 | render status: :bad_request, json: {message: @client_session.errors.full_messages.join(", ")} 20 | end 21 | end 22 | 23 | private 24 | def client_session_class 25 | @client_session_class ||= in_sandbox? ? SandboxClientSession : ClientSession 26 | end 27 | 28 | def token_class 29 | @token_class ||= in_sandbox? ? SandboxToken : Token 30 | end 31 | 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v1/features_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V1 2 | class FeaturesController < ApplicationController 3 | def index 4 | render :json => authorized_app.features 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v1/leaderboards_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V1 2 | class LeaderboardsController < ApplicationController 3 | 4 | def index 5 | if params[:tag] 6 | @leaderboards = authorized_app.leaderboards.tagged_with(params[:tag].to_s).order(:priority) 7 | else 8 | @leaderboards = authorized_app.leaderboards.order(:priority) 9 | end 10 | render json: @leaderboards.map {|x| x.api_fields(request_base_uri, in_sandbox?)} 11 | end 12 | 13 | def show 14 | err_message = nil 15 | lid = params[:id] && params[:id].to_i 16 | err_message = "You must pass a leaderboard id" unless lid 17 | 18 | if !err_message 19 | @leaderboard = authorized_app.leaderboards.find_by_id(lid) 20 | err_message = "Your app does not have a leaderboard with id: #{lid}" unless @leaderboard 21 | end 22 | 23 | if !err_message 24 | render json: @leaderboard.api_fields(request_base_uri, in_sandbox?) 25 | else 26 | render status: :bad_request, json: {message: err_message} 27 | end 28 | end 29 | 30 | def create 31 | @leaderboard = authorized_app.leaderboards.new(params[:leaderboard]) 32 | if @leaderboard.save 33 | render json: @leaderboard.api_fields(request_base_uri, in_sandbox?), status: :created 34 | else 35 | render json: @leaderboard.errors, status: :unprocessable_entity 36 | end 37 | end 38 | end 39 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v1/scores_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V1 2 | class ScoresController < ApplicationController 3 | before_filter :set_leaderboard 4 | 5 | def show 6 | @score = @leaderboard.send(scores_association).find(params[:id].to_i) 7 | render json: @score 8 | end 9 | 10 | def create 11 | err_message = nil 12 | err_code = nil 13 | user_id = params[:score].delete(:user_id) 14 | if user_id.blank? 15 | err_message = "Please pass a user_id with your score." 16 | err_code = :bad_request 17 | end 18 | 19 | if !err_message 20 | user = user_id && authorized_app.users.find_by_id(user_id.to_i) 21 | if !user 22 | err_message = "User with that ID is not subscribed to this app." 23 | err_code = 410 24 | end 25 | end 26 | 27 | if !err_message 28 | value = params[:score].delete(:value) 29 | @score = @leaderboard.send(scores_association).build(params[:score]) 30 | @score.value = value 31 | @score.user = user 32 | if !@score.save 33 | err_message = "#{@score.errors.full_messages.join(", ")}" 34 | err_code = :bad_request 35 | end 36 | end 37 | 38 | if err_message 39 | render status: err_code, json: {message: err_message} 40 | else 41 | render json: @score 42 | end 43 | end 44 | 45 | private 46 | def set_leaderboard 47 | l_id1 = params[:score] && params[:score].delete(:leaderboard_id) 48 | l_id2 = params.delete(:leaderboard_id) 49 | if(leaderboard_id = l_id1 || l_id2) 50 | @leaderboard = authorized_app.leaderboards.find_by_id(leaderboard_id.to_i) 51 | end 52 | 53 | unless @leaderboard 54 | render status: :forbidden, json: {message: "Pass a leaderboard_id that belongs to the app associated with app_key"} 55 | end 56 | end 57 | 58 | def scores_association 59 | in_sandbox? ? :sandbox_scores : :scores 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /dashboard/app/controllers/api/v1/users_controller.rb: -------------------------------------------------------------------------------- 1 | module Api::V1 2 | class UsersController < ApplicationController 3 | 4 | def create 5 | err_message = nil 6 | 7 | @user = authorized_app.find_or_create_subscribed_user(params[:user]) 8 | err_message = "Could not create that user." if @user.nil? 9 | err_message = "Couldn't subscribe user because:#{@user.errors.full_messages[0]}" if @user.errors.count != 0 10 | 11 | if !err_message 12 | render json: @user, status: :created 13 | else 14 | render status: :bad_request, json: {message: err_message} 15 | end 16 | end 17 | 18 | def update 19 | @user = authorized_app.developer.users.find_by_id(params[:id].to_i) 20 | if @user.nil? 21 | render status: 410, json: {message: "User with that id does not belong to you"} 22 | else 23 | params[:user].delete :id 24 | params[:user].delete :developer_id 25 | if @user.update_attributes(params[:user]) 26 | render status: :ok, json: @user 27 | else 28 | render status: :unprocessable_entity, json: {message: @user.errors.full_messages.join(', ')} 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/achievement_scores_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class AchievementScoresController < ApplicationController 3 | 4 | def destroy 5 | @achievement_score = AchievementScore.find(params[:id].to_i) 6 | if current_developer.authorized_to_delete_achievement_score?(@achievement_score) 7 | @achievement_score.destroy 8 | redirect_to achievement_scores_url, notice: "Score was deleted." 9 | else 10 | redirect_to root_url, notice: "You can't delete that score." 11 | end 12 | end 13 | end 14 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/achievements_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class AchievementsController < ApplicationController 3 | before_filter :set_app 4 | 5 | def index 6 | @achievements = @app.achievements 7 | end 8 | 9 | def show 10 | @achievement = @app.achievements.find(params[:id].to_i) 11 | @achievement_scores = @achievement.best_scores 12 | ActiveRecord::Associations::Preloader.new(@achievement_scores, [:user]).run 13 | end 14 | 15 | def new 16 | @achievement = @app.achievements.build 17 | end 18 | 19 | def edit 20 | @achievement = @app.achievements.find(params[:id].to_i) 21 | end 22 | 23 | def create 24 | @achievement = @app.achievements.new(params[:achievement]) 25 | 26 | if @achievement.save 27 | redirect_to [@app, @achievement], notice: 'Achievement was successfully created.' 28 | else 29 | render action: "new" 30 | end 31 | end 32 | 33 | def update 34 | params[:achievement].delete(:app_id) 35 | @achievement = @app.achievements.find(params[:id].to_i) 36 | 37 | if @achievement.update_attributes(params[:achievement]) 38 | redirect_to [@app, @achievement], notice: 'Achievement was successfully updated.' 39 | else 40 | render action: "edit" 41 | end 42 | end 43 | 44 | def destroy 45 | @achievement = @app.achievements.find_by_id(params[:id].to_i) 46 | if @achievement 47 | @achievement.destroy 48 | notice = "Destroyed achievement." 49 | else 50 | notice = "Achievement doesn't exist." 51 | end 52 | redirect_to app_achievements_url(@app), notice: notice 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/application_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class ApplicationController < ActionController::Base 3 | layout 'application' 4 | protect_from_forgery 5 | before_filter :require_login 6 | helper_method :current_developer 7 | 8 | private 9 | def current_developer_session 10 | return @current_developer_session if defined?(@current_developer_session) 11 | @current_developer_session = DeveloperSession.find 12 | end 13 | 14 | def current_developer 15 | return @current_developer if defined?(@current_developer) 16 | @current_developer = current_developer_session && current_developer_session.record 17 | end 18 | 19 | def require_login 20 | unless current_developer 21 | store_location 22 | if request.path == "/" 23 | redirect_to login_path 24 | else 25 | redirect_to login_path, notice: "You must be logged in to do that" 26 | end 27 | end 28 | end 29 | 30 | def store_location 31 | session[:return_to] = request.path 32 | end 33 | 34 | def redirect_back_or_default(default) 35 | redirect_to(session[:return_to] || default) 36 | session[:return_to] = nil 37 | end 38 | 39 | def request_base_uri 40 | request.protocol + request.host_with_port 41 | end 42 | 43 | def set_app 44 | @app = params[:app_id] && current_developer.apps.find(params[:app_id].to_i) 45 | if !@app 46 | render :status => :forbidden, :text => "Forbidden" 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/apps_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class AppsController < ApplicationController 3 | 4 | def index 5 | @apps = current_developer.apps 6 | end 7 | 8 | def show 9 | @app = current_developer.apps.find(params[:id].to_i) 10 | end 11 | 12 | def new 13 | @app = current_developer.apps.build 14 | end 15 | 16 | def edit 17 | @app = current_developer.apps.find(params[:id].to_i) 18 | end 19 | 20 | def create 21 | params[:app].delete :developer_id 22 | @app = current_developer.apps.build(params[:app]) 23 | if @app.save 24 | redirect_to @app, notice: 'App was successfully created.' 25 | else 26 | render action: "new" 27 | end 28 | end 29 | 30 | def update 31 | params[:app].delete :developer_id 32 | @app = current_developer.apps.find(params[:id].to_i) 33 | if @app.update_attributes(params[:app]) 34 | redirect_to @app, notice: 'App was successfully updated.' 35 | else 36 | render action: "edit" 37 | end 38 | end 39 | 40 | def destroy 41 | @app = current_developer.apps.find(params[:id].to_i) 42 | @app.destroy 43 | redirect_to apps_url 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/change_password_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class ChangePasswordController < ApplicationController 3 | 4 | # GET /change_password/new 5 | def new 6 | @change_password = ChangePassword.new 7 | end 8 | 9 | # POST /change_password 10 | def create 11 | params.delete(:developer) 12 | @change_password = ChangePassword.new(params[:change_password].merge(developer: current_developer)) 13 | if @change_password.save 14 | redirect_to developer_path(current_developer), notice: 'Change password was successfully created.' 15 | else 16 | render action: "new" 17 | end 18 | end 19 | end 20 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/developer_sessions_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class DeveloperSessionsController < ApplicationController 3 | skip_before_filter :require_login, :only => [:new, :create] 4 | 5 | # GET /developer_sessions/new 6 | def new 7 | @developer_session = DeveloperSession.new 8 | end 9 | 10 | # POST /developer_sessions 11 | def create 12 | @developer_session = DeveloperSession.new(params[:developer_session]) 13 | if @developer_session.save 14 | flash[:notice] = "Login successful!" 15 | redirect_back_or_default root_url 16 | else 17 | render :action => :new 18 | end 19 | end 20 | 21 | # DELETE /developer_sessions/1 22 | def destroy 23 | current_developer_session.destroy 24 | flash[:notice] = "Logout successful!" 25 | redirect_to root_url 26 | end 27 | end 28 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/developers_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class DevelopersController < ApplicationController 3 | # Nothing required to hit the signup page. 4 | skip_before_filter :require_login, :only => [:new, :create] 5 | before_filter :set_developer, :except => [:new, :create] 6 | 7 | def show 8 | end 9 | 10 | def new 11 | @developer = Developer.new 12 | end 13 | 14 | def edit 15 | end 16 | 17 | def create 18 | render text: "Sorry, OpenKit has been shutdown and is not accepting new users." 19 | end 20 | 21 | def update 22 | @developer.assign_attributes(params[:developer]) 23 | if @developer.save 24 | redirect_to @developer, notice: 'Developer was successfully updated.' 25 | else 26 | render action: "edit" 27 | end 28 | end 29 | 30 | def destroy 31 | @developer.destroy 32 | redirect_to developers_url, notice: 'Your account was destroyed' 33 | end 34 | 35 | private 36 | def set_developer 37 | @developer = Developer.find(params[:id].to_i) 38 | unless @developer && (current_developer == @developer) 39 | render :text => "Forbidden", :status => :forbidden 40 | end 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/password_resets_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class PasswordResetsController < ApplicationController 3 | skip_before_filter :require_login 4 | before_filter :load_developer_using_perishable_token, :only => [ :edit, :update ] 5 | 6 | def new 7 | end 8 | 9 | def create 10 | @developer = Developer.find_by(emil: params[:email].to_s) 11 | if @developer 12 | @developer.deliver_password_reset_instructions! 13 | flash[:notice] = "Instructions have been sent. Please check your spam folder if you do not see an email from us within a few minutes." 14 | redirect_to login_path 15 | else 16 | flash.now[:error] = "No developer was found with email address #{params[:email]}" 17 | render :action => :new 18 | end 19 | end 20 | 21 | def edit 22 | end 23 | 24 | def update 25 | @developer.password = params[:password].to_s 26 | @developer.password_confirmation = params[:password_confirmation].to_s 27 | 28 | # Use @developer.save_without_session_maintenance instead if you 29 | # don't want the developer to be signed in automatically. 30 | if @developer.save 31 | flash[:notice] = "Your password was successfully updated" 32 | redirect_to root_url 33 | else 34 | render :action => :edit 35 | end 36 | end 37 | 38 | 39 | private 40 | 41 | def load_developer_using_perishable_token 42 | @developer = Developer.find_using_perishable_token(params[:id].to_s) 43 | unless @developer 44 | flash[:error] = "We're sorry, but we could not locate your account" 45 | redirect_to root_url 46 | end 47 | end 48 | end 49 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/production_push_certs_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class ProductionPushCertsController < ApplicationController 3 | before_filter :set_app 4 | 5 | def new 6 | @production_push_cert = ProductionPushCert.new(@app.app_key) 7 | end 8 | 9 | def create 10 | @production_push_cert = ProductionPushCert.new(@app.app_key) 11 | @production_push_cert.p12 = params[:production_push_cert]['p12'] 12 | @production_push_cert.p12_pw = params[:production_push_cert]['p12_pw'] 13 | 14 | if @production_push_cert.save 15 | redirect_to app_push_notes_path(@app), notice: 'Production push cert was successfully created.' 16 | else 17 | render action: 'new' 18 | end 19 | end 20 | 21 | def destroy 22 | if @app.production_push_cert.destroy 23 | redirect_to app_push_notes_path(@app), notice: 'Deleted the production push cert.' 24 | else 25 | redirect_to app_push_notes_path(@app), notice: 'Could not delete that push cert, contact lou@openkit.io for help.' 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/push_notes_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class PushNotesController < ApplicationController 3 | before_filter :set_app 4 | 5 | def info 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/sandbox_push_certs_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class SandboxPushCertsController < ApplicationController 3 | before_filter :set_app 4 | 5 | def new 6 | @sandbox_push_cert = SandboxPushCert.new(@app.app_key) 7 | end 8 | 9 | def create 10 | @sandbox_push_cert = SandboxPushCert.new(@app.app_key) 11 | @sandbox_push_cert.p12 = params[:sandbox_push_cert]['p12'] 12 | @sandbox_push_cert.p12_pw = params[:sandbox_push_cert]['p12_pw'] 13 | 14 | if @sandbox_push_cert.save 15 | redirect_to app_push_notes_path(@app), notice: 'Sandbox push cert was successfully created.' 16 | else 17 | render action: 'new' 18 | end 19 | end 20 | 21 | def destroy 22 | if @app.sandbox_push_cert.destroy 23 | redirect_to app_push_notes_path(@app), notice: 'Deleted the sandbox push cert.' 24 | else 25 | redirect_to app_push_notes_path(@app), notice: 'Could not delete that push cert, contact lou@openkit.io for help.' 26 | end 27 | end 28 | 29 | def test_project 30 | if @app.sandbox_push_cert.nil? 31 | render :text => "Please upload a sandbox push certificate first." 32 | elsif @app.sandbox_push_cert.bundle_identifier.nil? 33 | render :text => "Could not parse the bundle identifier from your push certificate. Please contact lou@openkit.io" 34 | else 35 | p = PushTestProject.new(@app.sandbox_push_cert.bundle_identifier) 36 | if !p.construct 37 | render :text => "Could not create zip of project. Please contact lou@openkit.io" 38 | else 39 | send_file p.path_to_zip 40 | end 41 | end 42 | end 43 | 44 | def test_push 45 | if params['token'] && params['body'] 46 | @token = params['token'].to_s 47 | body = params['body'].to_s 48 | if !body.empty? 49 | payload = {aps: {alert: body, badge: 0, sound: "default"}} 50 | if PushQueue.add(@app.sandbox_push_cert.pem_path, @token, payload, true) 51 | flash[:notice] = "Sending to Apple..." 52 | end 53 | end 54 | end 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/scores_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class ScoresController < ApplicationController 3 | 4 | def destroy 5 | @score = Score.find(params[:id].to_i) 6 | if current_developer.authorized_to_delete_score?(@score) 7 | @score.destroy 8 | redirect_to scores_url, notice: "Score was deleted." 9 | else 10 | redirect_to root_url, notice: "You can't delete that score." 11 | end 12 | end 13 | end 14 | end -------------------------------------------------------------------------------- /dashboard/app/controllers/dashboard/turns_controller.rb: -------------------------------------------------------------------------------- 1 | module Dashboard 2 | class TurnsController < ApplicationController 3 | def new 4 | @turn = Turn.new 5 | end 6 | 7 | def create 8 | @turn = Turn.new(params[:turn]) 9 | if @turn.save 10 | render :text => 'saved' 11 | else 12 | render action: "new" 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /dashboard/app/helpers/achievement_scores_helper.rb: -------------------------------------------------------------------------------- 1 | module AchievementScoresHelper 2 | end 3 | -------------------------------------------------------------------------------- /dashboard/app/helpers/achievements_helper.rb: -------------------------------------------------------------------------------- 1 | module AchievementsHelper 2 | 3 | end 4 | -------------------------------------------------------------------------------- /dashboard/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | def logging_in? 3 | request.path == login_path 4 | end 5 | 6 | def display_login? 7 | !current_developer && !logging_in? 8 | end 9 | 10 | def display_logout? 11 | !!current_developer 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /dashboard/app/helpers/apps_helper.rb: -------------------------------------------------------------------------------- 1 | module AppsHelper 2 | end 3 | -------------------------------------------------------------------------------- /dashboard/app/helpers/change_password_helper.rb: -------------------------------------------------------------------------------- 1 | module ChangePasswordHelper 2 | end 3 | -------------------------------------------------------------------------------- /dashboard/app/helpers/leaderboards_helper.rb: -------------------------------------------------------------------------------- 1 | module LeaderboardsHelper 2 | end 3 | -------------------------------------------------------------------------------- /dashboard/app/helpers/password_resets_helper.rb: -------------------------------------------------------------------------------- 1 | module PasswordResetsHelper 2 | end 3 | -------------------------------------------------------------------------------- /dashboard/app/helpers/scores_helper.rb: -------------------------------------------------------------------------------- 1 | module ScoresHelper 2 | end 3 | -------------------------------------------------------------------------------- /dashboard/app/helpers/users_helper.rb: -------------------------------------------------------------------------------- 1 | module UsersHelper 2 | end 3 | -------------------------------------------------------------------------------- /dashboard/app/mailers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/mailers/.gitkeep -------------------------------------------------------------------------------- /dashboard/app/mailers/developer_mailer.rb: -------------------------------------------------------------------------------- 1 | class DeveloperMailer < ActionMailer::Base 2 | default from: "OpenKit " 3 | default content_type: "text/html" 4 | 5 | def password_reset_instructions(developer) 6 | @edit_password_reset_url = edit_password_reset_url(developer.perishable_token) 7 | mail(template_path: 'dashboard/developer_mailer', template_name: 'password_reset_instructions', to: developer.email, subject: "OpenKit Reset Password Instructions") 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/app/models/.gitkeep -------------------------------------------------------------------------------- /dashboard/app/models/achievement_score.rb: -------------------------------------------------------------------------------- 1 | class AchievementScore < ActiveRecord::Base 2 | include BaseAchievementScore 3 | end -------------------------------------------------------------------------------- /dashboard/app/models/api_whitelist.rb: -------------------------------------------------------------------------------- 1 | class ApiWhitelist < ActiveRecord::Base 2 | attr_accessible :app_key, :version 3 | end 4 | -------------------------------------------------------------------------------- /dashboard/app/models/base_achievement_score.rb: -------------------------------------------------------------------------------- 1 | module BaseAchievementScore 2 | 3 | def self.included(base) 4 | base.belongs_to :user 5 | base.belongs_to :achievement 6 | base.attr_accessible :progress 7 | base.send :extend, ClassMethods 8 | base.send :include, InstanceMethods 9 | end 10 | 11 | module ClassMethods 12 | end 13 | 14 | module InstanceMethods 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /dashboard/app/models/base_client_session.rb: -------------------------------------------------------------------------------- 1 | module BaseClientSession 2 | 3 | def self.included(base) 4 | base.attr_accessible :client_created_at, :client_db_version, :custom_id, :fb_id, :google_id, :ok_id, :push_token, :uuid, :app_id 5 | base.send :extend, ClassMethods 6 | base.send :include, InstanceMethods 7 | end 8 | 9 | module ClassMethods 10 | end 11 | 12 | module InstanceMethods 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /dashboard/app/models/base_token.rb: -------------------------------------------------------------------------------- 1 | module BaseToken 2 | 3 | def self.included(base) 4 | base.attr_accessible :apns_token, :app_id, :user_id 5 | base.belongs_to :app 6 | base.belongs_to :user 7 | base.send :extend, ClassMethods 8 | base.send :include, InstanceMethods 9 | end 10 | 11 | module ClassMethods 12 | end 13 | 14 | module InstanceMethods 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /dashboard/app/models/change_password.rb: -------------------------------------------------------------------------------- 1 | class ChangePassword 2 | 3 | attr_accessor :developer 4 | attr_accessor :current_password 5 | attr_accessor :new_password, :new_password_confirmation 6 | 7 | include ActiveModel::Validations 8 | include ActiveModel::Conversion 9 | extend ActiveModel::Naming 10 | 11 | validates_presence_of :current_password, :new_password, :new_password_confirmation 12 | validate :current_password_matches 13 | 14 | def initialize(attributes={}) 15 | attributes && attributes.each do |name, value| 16 | send("#{name}=", value) if respond_to? name.to_sym 17 | end 18 | end 19 | 20 | def persisted? 21 | false 22 | end 23 | 24 | def self.inspect 25 | "#<#{ self.to_s} #{ self.attributes.collect{ |e| ":#{ e }" }.join(', ') }>" 26 | end 27 | 28 | def save 29 | if self.valid? 30 | @developer.password = new_password 31 | @developer.password_confirmation = new_password_confirmation 32 | if @developer.save 33 | return true 34 | else 35 | errors.merge!(@developer.errors) 36 | end 37 | end 38 | return false 39 | end 40 | 41 | private 42 | def current_password_matches 43 | devSession = DeveloperSession.new({:email => @developer.email, 44 | :password => @current_password}) 45 | unless devSession.valid? 46 | errors.add(:current_password, "is incorrect.") 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /dashboard/app/models/client_session.rb: -------------------------------------------------------------------------------- 1 | class ClientSession < ActiveRecord::Base 2 | include BaseClientSession 3 | end 4 | -------------------------------------------------------------------------------- /dashboard/app/models/developer.rb: -------------------------------------------------------------------------------- 1 | # Interface: 2 | # developer.users 3 | # developer.apps 4 | class Developer < ActiveRecord::Base 5 | acts_as_authentic do |c| 6 | c.perishable_token_valid_for = 24.hours 7 | end 8 | attr_accessible :email, :password, :password_confirmation, :name 9 | 10 | has_many :apps, :dependent => :destroy 11 | has_many :users 12 | 13 | validates_presence_of :email 14 | validates_uniqueness_of :email 15 | 16 | def authorized_to_delete_score?(score) 17 | score.leaderboard.app.developer == self 18 | end 19 | 20 | def authorized_to_delete_achievement_score?(achievement_score) 21 | achievement_score.achievement.app.developer == self 22 | end 23 | 24 | def has_user?(u) 25 | raise ArgumentError unless u.is_a?(Fixnum) || u.is_a?(User) 26 | u = User.find_by_id(u) if u.is_a?(Fixnum) 27 | u && (u.developer_id == id) 28 | end 29 | 30 | # Remove the deliver message when using Delayed Job 3. See: 31 | # https://github.com/collectiveidea/delayed_job 32 | def deliver_password_reset_instructions! 33 | reset_perishable_token! 34 | DeveloperMailer.delay.password_reset_instructions(self) 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /dashboard/app/models/developer_session.rb: -------------------------------------------------------------------------------- 1 | class DeveloperSession < Authlogic::Session::Base 2 | remember_me true 3 | remember_me_for 30.days 4 | end 5 | 6 | -------------------------------------------------------------------------------- /dashboard/app/models/leaderboard.rb: -------------------------------------------------------------------------------- 1 | class Leaderboard < ActiveRecord::Base 2 | attr_accessible :name, :icon, :sort_type, :gamecenter_id, :gpg_id, :priority, :tag_list 3 | attr_accessible :type 4 | validates_presence_of :name, :sort_type 5 | validates_uniqueness_of :name, :scope => :app_id 6 | acts_as_taggable 7 | 8 | belongs_to :app 9 | has_many :scores, :dependent => :delete_all 10 | has_many :sandbox_scores, :dependent => :delete_all 11 | 12 | def api_fields(base_uri, sandbox) 13 | { 14 | :id => id, 15 | :app_id => app_id, 16 | :name => name, 17 | :created_at => created_at, 18 | :updated_at => updated_at, 19 | :sort_type => sort_type, 20 | :icon_url => PaperclipHelper.uri_for(icon, base_uri), 21 | :player_count => player_count(sandbox), 22 | :gamecenter_id => gamecenter_id, 23 | :gpg_id => gpg_id 24 | } 25 | end 26 | 27 | has_attached_file :icon, :default_url => 'https://ok-shared.s3-us-west-2.amazonaws.com/leaderboard_icon.png' 28 | 29 | HIGH_VALUE_SORT_TYPE = "HighValue" 30 | LOW_VALUE_SORT_TYPE = "LowValue" 31 | 32 | 33 | public 34 | def is_high_value? 35 | sort_type == HIGH_VALUE_SORT_TYPE 36 | end 37 | 38 | def is_low_value? 39 | sort_type == LOW_VALUE_SORT_TYPE 40 | end 41 | 42 | def player_count(sandbox) 43 | k = sandbox ? "leaderboard:#{id}:sandbox_players" : "leaderboard:#{id}:players" 44 | OKRedis.scard(k) 45 | end 46 | 47 | private 48 | def extrema_func_name 49 | sql_lookup[sort_type][:extrema_func_name] 50 | end 51 | 52 | def order_keyword 53 | sql_lookup[sort_type][:order_keyword] 54 | end 55 | 56 | def sql_lookup 57 | @sql_lookup ||= { 58 | HIGH_VALUE_SORT_TYPE => { 59 | :extrema_func_name => "MAX", 60 | :order_keyword => "DESC", 61 | }, 62 | LOW_VALUE_SORT_TYPE => { 63 | :extrema_func_name => "MIN", 64 | :order_keyword => "ASC", 65 | } 66 | } 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /dashboard/app/models/oauth_nonce.rb: -------------------------------------------------------------------------------- 1 | # Simple store of nonces. The OAuth Spec requires that any given pair of nonce and timestamps are unique. 2 | # Thus you can use the same nonce with a different timestamp and viceversa. 3 | class OauthNonce < ActiveRecord::Base 4 | validates_presence_of :nonce, :timestamp 5 | validates_uniqueness_of :nonce, :scope => :timestamp 6 | 7 | # Remembers a nonce and it's associated timestamp. It returns false if it has already been used 8 | def self.remember(nonce, timestamp) 9 | oa_nonce = OauthNonce.new 10 | oa_nonce.nonce = nonce 11 | oa_nonce.timestamp = timestamp 12 | oa_nonce.save 13 | return false if oa_nonce.new_record? 14 | oa_nonce 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /dashboard/app/models/production_push_cert.rb: -------------------------------------------------------------------------------- 1 | class ProductionPushCert < PushCert 2 | set_local_path OKConfig[:apns_pem_path] 3 | end 4 | -------------------------------------------------------------------------------- /dashboard/app/models/sandbox_achievement_score.rb: -------------------------------------------------------------------------------- 1 | class SandboxAchievementScore < ActiveRecord::Base 2 | include BaseAchievementScore 3 | end 4 | 5 | -------------------------------------------------------------------------------- /dashboard/app/models/sandbox_client_session.rb: -------------------------------------------------------------------------------- 1 | class SandboxClientSession < ActiveRecord::Base 2 | include BaseClientSession 3 | end 4 | -------------------------------------------------------------------------------- /dashboard/app/models/sandbox_push_cert.rb: -------------------------------------------------------------------------------- 1 | class SandboxPushCert < PushCert 2 | set_local_path OKConfig[:apns_sandbox_pem_path] 3 | end 4 | -------------------------------------------------------------------------------- /dashboard/app/models/sandbox_score.rb: -------------------------------------------------------------------------------- 1 | class SandboxScore < ActiveRecord::Base 2 | include BaseScore 3 | after_create :add_player_to_sandbox_set 4 | 5 | private 6 | def add_player_to_sandbox_set 7 | k = "leaderboard:#{leaderboard_id}:sandbox_players" 8 | OKRedis.sadd(k, user_id) 9 | end 10 | end 11 | 12 | -------------------------------------------------------------------------------- /dashboard/app/models/sandbox_token.rb: -------------------------------------------------------------------------------- 1 | class SandboxToken < ActiveRecord::Base 2 | include BaseToken 3 | end 4 | -------------------------------------------------------------------------------- /dashboard/app/models/score.rb: -------------------------------------------------------------------------------- 1 | class Score < ActiveRecord::Base 2 | include BaseScore 3 | after_create :add_player_to_set 4 | 5 | private 6 | def add_player_to_set 7 | k = "leaderboard:#{leaderboard_id}:players" 8 | OKRedis.sadd(k, user_id) 9 | end 10 | end 11 | 12 | -------------------------------------------------------------------------------- /dashboard/app/models/subscription.rb: -------------------------------------------------------------------------------- 1 | class Subscription < ActiveRecord::Base 2 | belongs_to :app 3 | belongs_to :user 4 | end 5 | -------------------------------------------------------------------------------- /dashboard/app/models/token.rb: -------------------------------------------------------------------------------- 1 | class Token < ActiveRecord::Base 2 | include BaseToken 3 | end 4 | -------------------------------------------------------------------------------- /dashboard/app/models/turn.rb: -------------------------------------------------------------------------------- 1 | class Turn < ActiveRecord::Base 2 | attr_accessible :uuid, :meta_doc, :user_id 3 | has_attached_file :meta_doc 4 | end 5 | -------------------------------------------------------------------------------- /dashboard/app/models/user.rb: -------------------------------------------------------------------------------- 1 | # Interface: 2 | # user.apps 3 | # user.developer 4 | class User < ActiveRecord::Base 5 | attr_accessible :nick, :fb_id, :twitter_id, :google_id, :custom_id, :gamecenter_id 6 | attr_accessor :cloud_data 7 | validates_presence_of :nick 8 | validate :has_service_id 9 | 10 | has_many :scores, :dependent => :delete_all 11 | has_many :subscriptions 12 | has_many :apps, :through => :subscriptions 13 | has_many :tokens 14 | has_many :sandbox_tokens 15 | belongs_to :developer 16 | 17 | class << self 18 | def unreferenced 19 | joins("left join subscriptions on subscriptions.user_id=users.id").where("subscriptions.user_id IS NULL").select("distinct users.*") 20 | end 21 | end 22 | 23 | private 24 | def has_service_id 25 | unless fb_id || twitter_id || google_id || custom_id || gamecenter_id 26 | errors.add(:base, "Please provide a service id for this user (fb_id, twitter_id, google_id, gamecenter_id, or custom_id)") 27 | end 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/achievements/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for([@app, @achievement]) do |f| %> 2 | <% if @achievement.errors.any? %> 3 |
4 |

<%= pluralize(@achievement.errors.count, "error") %> prohibited this achievement from being saved:

5 | 6 |
    7 | <% @achievement.errors.full_messages.each do |msg| %> 8 |
  • <%= msg %>
  • 9 | <% end %> 10 |
11 |
12 | <% end %> 13 | 14 |
15 | <%= f.label :name %> 16 | <%= f.text_field :name %> 17 |
18 | 19 |
20 | <%= f.label :desc %> 21 | <%= f.text_field :desc %> 22 |
23 | 24 | 25 |
26 | <%= f.label :goal %> 27 | <%= f.number_field :goal %> 28 |
29 | 30 | 31 |
32 | <%= f.label :points %> 33 | <%= f.number_field :points %> 34 |
35 | 36 |
37 | <%# f.label :icon %> 38 | 39 | <%= f.file_field :icon %> 40 |
41 | 42 | <% if params[:action] == "edit" %> 43 | <%# image_tag @achievement.icon.url if @achievement.icon.file? %> 44 | <% end %> 45 | 46 |
47 | <%= f.submit %> <%= link_to 'Cancel', [@app, @achievement], {:class=> 'cancel'} %> 48 |
49 | 50 | <% end %> 51 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/achievements/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Edit Achievement

3 |
4 | 5 |
6 | 7 | <%= render 'form' %> 8 | 9 |
10 | 11 | <%# link_to 'Show', [@app, @achievement] %> 12 | <%# link_to 'Back', app_achievements_path(@app) %> 13 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/achievements/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= link_to 'Your Apps', apps_path %> / <%= link_to @app.name, @app %> / Achievements

3 | <%= link_to new_app_achievement_path(@app), {:class => 'header_button'} do %> 4 | Add a New Achievement 5 | <% end %> 6 |
7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | <% if @achievements.empty? %> 19 | 20 | 21 | 22 | <% else %> 23 | <% @achievements.each do |achievement| %> 24 | 25 | 26 | 27 | 28 | 29 | 30 | 38 | 39 | <% end %> 40 | 41 | <% end %> 42 | 43 |
IconNameIDGoalPoints
There are no achievements for this app. <%= link_to 'Add a New Achievement', new_app_achievement_path(@app) %>
<%= image_tag achievement.icon.url, {:class=> 'leaderboard_icon'} %><%= link_to achievement.name, [@app, achievement] %><%= achievement.id %><%= achievement.goal %><%= achievement.points %> 31 | <%= link_to edit_app_achievement_path(@app, achievement) do %> 32 | Edit 33 | <% end %> 34 | <%= link_to [@app, achievement], method: :delete, data: { confirm: 'Are you sure?' } do %> 35 | Destroy 36 | <% end %> 37 |
44 |
45 | 46 | <%# link_to 'Back', app_path(@app) %> 47 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/achievements/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

New Achievement

3 |
4 | 5 |
6 | 7 | <%= render 'form' %> 8 | 9 |
10 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/achievements/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= link_to 'Your Apps', apps_path %> / <%= link_to @app.name, @app %> / <%= link_to 'Achievements', app_achievements_path(@app) %> / <%= @achievement.name %>

3 | <%= link_to edit_app_achievement_path(@app, @achievement), {:class=> 'header_button'} do %> 4 | Edit Achievement 5 | <% end %> 6 |
7 | 8 |
9 | 10 |
11 |
Achievement Details
12 |
    13 |
  • Icon: <%= image_tag @achievement.icon.url, {:class=> 'leaderboard_icon'} %>
  • 14 |
  • Name: <%= @achievement.name %>
  • 15 |
  • Desc: <%= @achievement.desc %>
  • 16 |
  • ID: <%= @achievement.id %>
  • 17 |
  • Goal: <%= @achievement.goal %>
  • 18 |
  • Points: <%= @achievement.points %>
  • 19 |
20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | <% if @achievement_scores.empty? %> 32 | 33 | 34 | 35 | <% else %> 36 | 37 | <% @achievement_scores.each do |score| %> 38 | 39 | 40 | 41 | 42 | 43 | <% end %> 44 | 45 | <% end %> 46 | 47 |
NickCurrent progressScored at
There are no players in this achievement.
<%= score.user.nick %><%= score.progress %><%= score.created_at %>
48 | 49 |
50 | 51 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/apps/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@app) do |f| %> 2 | 3 | <% if @app.errors.any? %> 4 |
5 |

<%= pluralize(@app.errors.count, "error") %> prohibited this app from being saved:

6 | 7 |
    8 | <% @app.errors.full_messages.each do |msg| %> 9 |
  • <%= msg %>
  • 10 | <% end %> 11 |
12 |
13 | <% end %> 14 | 15 |
16 | <%= f.label :name %> 17 | <%= f.text_field :name %> 18 |
19 | 20 |
21 | <%= f.label :icon %> 22 | <%= f.file_field :icon %> 23 |
24 | 25 |
26 | <%= f.label :fbid, "Facebook App ID (optional):"%> 27 | <%= f.text_field :fbid %> 28 |
29 | 30 | <% if params[:action] == "edit" %> 31 | <%# image_tag @app.icon.url if @app.icon.file? %> 32 | <% end %> 33 | 34 |
35 | <%= f.submit %> <%= link_to 'Cancel', @app, {:class=> 'cancel'} %> 36 |
37 | 38 | <% end %> 39 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/apps/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Edit App

3 |
4 | 5 |
6 | 7 | <%= render 'form' %> 8 | 9 |
10 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/apps/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Add a New App

3 |
4 | 5 |
6 | 7 | <%= render 'form' %> 8 | 9 |
10 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/change_password/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@change_password, :url => change_password_index_path) do |f| %> 2 | <% if @change_password.errors.any? %> 3 |
4 |

<%= pluralize(@change_password.errors.count, "error") %> prohibited this change_password from being saved:

5 | 6 |
    7 | <% @change_password.errors.full_messages.each do |msg| %> 8 |
  • <%= msg %>
  • 9 | <% end %> 10 |
11 |
12 | <% end %> 13 | 14 |
15 | <%= f.label :current_password %> 16 | <%= f.password_field :current_password %> 17 |
18 | 19 |
20 | <%= f.label :new_password %> 21 | <%= f.password_field :new_password %> 22 |
23 | 24 |
25 | <%= f.label :new_password_confirmation %> 26 | <%= f.password_field :new_password_confirmation %> 27 |
28 | 29 |
30 | <%= f.submit %> <%= link_to 'Cancel', developer_path(current_developer), {:class=>"cancel"} %> 31 |
32 | <% end %> 33 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/change_password/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Change Password

3 |
4 | 5 |
6 | 7 | <%= render 'form' %> 8 | 9 |
10 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/developer_mailer/password_reset_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Password Reset Instructions

2 | 3 |

4 | A request to reset your password has been made. If you did not make 5 | this request, simply ignore this email. If you did make this 6 | request, please follow the link below. 7 |

8 | 9 | <%= link_to "Reset Password!", @edit_password_reset_url %> 10 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/developer_sessions/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@developer_session) do |f| %> 2 | 3 |

Log In

4 | 5 | <% if @developer_session.errors.any? %> 6 |
7 |

Could not log in:

8 |
    9 | <% @developer_session.errors.full_messages.each do |msg| %> 10 |
  • <%= msg %>
  • 11 | <% end %> 12 |
13 |
14 | <% end %> 15 | 16 |
17 | <%= f.label :email %> 18 | <%= f.text_field :email %> 19 |
20 | 21 |
22 | <%= f.label :password %> 23 | <%= f.password_field :password %> 24 |
25 | 26 |
27 | <%= f.submit "Login" %> 28 |
29 | 30 | <% end %> 31 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/developer_sessions/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 |

<%= image_tag 'login_logo.png' %>

4 | 5 | <%= render 'form' %> 6 | 7 |

Forgot your password? Click here

8 |

Don't have an account? <%= link_to 'Sign Up', new_developer_path %>

9 | 10 |
11 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/developers/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@developer) do |f| %> 2 | 3 |

Sign up

4 | 5 | <% if @developer.errors.any? %> 6 |
7 |

<%= pluralize(@developer.errors.count, "error") %>:

8 | 9 |
    10 | <% @developer.errors.full_messages.each do |msg| %> 11 |
  • <%= msg %>
  • 12 | <% end %> 13 |
14 |
15 | <% end %> 16 | 17 |
18 | <%= f.label :email %> 19 | <%= f.text_field :email %> 20 |
21 | 22 | <% if params[:action] != "edit" %> 23 |
24 | <%= f.label :password %> 25 | <%= f.password_field :password %> 26 |
27 | 28 |
29 | <%= f.label :password_confirmation %> 30 | <%= f.password_field :password_confirmation %> 31 |
32 | <% end %> 33 | 34 |

By signing up, you are also accepting our License Agreement and Privacy Policy.

35 | 36 |
37 | <%= f.submit "Sign Up" %> 38 |
39 | 40 | <% end %> 41 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/developers/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Edit Account

3 |
4 | 5 |
6 | <%= render 'form' %> 7 |
8 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/developers/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 |

<%= image_tag 'login_logo.png' %>

4 | Sorry, OpenKit has been shutdown and is not accepting new users. 5 | 6 |
7 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/developers/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Account

3 | <%= link_to edit_developer_path(@developer), {:class => 'header_button'} do %> 4 | Edit Account 5 | <% end %> 6 |
7 | 8 |
9 | 10 |
11 |
12 |
    13 |
  • <%= link_to 'Change my password', new_change_password_path %>
  • 14 |
15 |
16 |
17 | 18 |
19 |
20 |
Your Info
21 |
    22 |
  • Email: <%= @developer.email %>
  • 23 |
  • 24 |
25 |
26 |
27 | 28 | 29 |
30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/leaderboards/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Edit Leaderboard

3 |
4 | 5 |
6 | 7 | <%= render 'form' %> 8 | 9 |
10 | 11 | <%# link_to 'Show', [@app, @leaderboard] %> 12 | <%# link_to 'Back', app_leaderboards_path(@app) %> 13 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/leaderboards/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= link_to 'Your Apps', apps_path %> / <%= link_to @app.name, @app %> / Leaderboards

3 | <%= link_to new_app_leaderboard_path(@app), {:class => 'header_button'} do %> 4 | Add a New Leaderboard 5 | <% end %> 6 |
7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | <% if @leaderboards.empty? %> 21 | 22 | 23 | 24 | <% else %> 25 | <% @leaderboards.each do |leaderboard| %> 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 41 | 42 | <% end %> 43 | 44 | <% end %> 45 | 46 |
IconNameIDGame Center IDGoogle Play Games IDTag List
There are no leaderboards for this app. <%= link_to 'Add a New Leaderboard', new_app_leaderboard_path(@app) %>
<%= image_tag leaderboard.icon.url, {:class=> 'leaderboard_icon'} %><%= link_to leaderboard.name, [@app, leaderboard] %><%= leaderboard.id %><%= leaderboard.gamecenter_id %><%= leaderboard.gpg_id %><%= leaderboard.tag_list %> 34 | <%= link_to edit_app_leaderboard_path(@app, leaderboard) do %> 35 | Edit 36 | <% end %> 37 | <%= link_to [@app, leaderboard], method: :delete, data: { confirm: 'Are you sure?' } do %> 38 | Destroy 39 | <% end %> 40 |
47 |
48 | 49 | <%# link_to 'Back', app_path(@app) %> 50 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/leaderboards/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

New Leaderboard

3 |
4 | 5 |
6 | 7 | <%= render 'form' %> 8 | 9 |
10 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/password_resets/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= image_tag 'login_logo.png' %>

3 | 4 | <%= form_tag password_reset_path, :method => :put do %> 5 |

Update Password

6 | <%= label_tag :password %>
7 | <%= password_field_tag :password %> 8 | 9 | <%= label_tag :password_confirmation %>
10 | <%= password_field_tag :password_confirmation %> 11 | <%= submit_tag "Update Password" %> 12 | <% end %> 13 | 14 |
15 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/password_resets/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 |

<%= image_tag 'login_logo.png' %>

4 | 5 | <%= form_tag password_resets_path do %> 6 | 7 |

Reset Password

8 | 9 |
10 | 11 | <%= text_field_tag :email %> 12 |
13 | 14 | <%= submit_tag "Reset Password" %> 15 | 16 | <% end %> 17 | 18 | 19 |

<%= link_to 'Back to Login', login_path %>

20 | 21 |
22 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/production_push_certs/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= link_to 'Your Apps', apps_path %> / <%= link_to @app.name, @app %> 3 | / <%= link_to 'Push Challenges', app_push_notes_path(@app) %> 4 | / Upload Production Push Cert 5 |

6 |
7 | 8 |
9 | <% if @app.production_push_cert %> 10 |
You have already uploaded a production push cert. 11 |
12 | <% else %> 13 | Upload a production push cert: 14 | <%= form_for(@production_push_cert, :url => app_production_push_cert_path) do |f| %> 15 | 16 | <% if @production_push_cert.errors.any? %> 17 |
18 |

<%= pluralize(@production_push_cert.errors.count, "error") %> prohibited the push cert from being saved:

19 | 20 |
    21 | <% @production_push_cert.errors.full_messages.each do |msg| %> 22 |
  • <%= msg %>
  • 23 | <% end %> 24 |
25 |
26 | <% end %> 27 |
28 | <%= f.label :p12, "Production Push Cert in .p12 format:" %> 29 | <%= f.file_field :p12 %> 30 |
31 |
32 | <%= f.label :p12_pw, "Password for .p12 file:" %> 33 | <%= f.password_field :p12_pw %> 34 |
35 | <%= f.submit %> 36 | <% end %> 37 | <% end %> 38 |
39 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/push_notes/info.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= link_to 'Your Apps', apps_path %> / <%= link_to @app.name, @app %> / Push Challenges

3 |
4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | <% if @app.sandbox_push_cert %> 16 | 17 | 21 | <% else %> 22 | 23 | 24 | <% end %> 25 | 26 | 27 | 28 | <% if @app.production_push_cert %> 29 | 30 | 31 | <% else %> 32 | 33 | 34 | <% end %> 35 | 36 |
EnvironmentHas Certificate?Action
SandboxYes 18 | <%= link_to 'remove', app_sandbox_push_cert_path(@app), :method => :delete, :confirm => "Are you sure?" %>   |   19 | <%= link_to 'send a test push', app_sandbox_test_push_path(@app) %> 20 | No<%= link_to 'upload', new_app_sandbox_push_cert_path(@app) %>
ProductionYes<%= link_to 'remove', app_production_push_cert_path(@app), :method => :delete, :confirm => "Are you sure?" %>No<%= link_to 'upload', new_app_production_push_cert_path(@app) %>
37 | 38 |
39 | 40 |
41 |
42 |
What are Push Challenges?
43 |
  • Configure your leaderboards to send push notifications as ranks change.
44 |
45 |
46 | 47 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/sandbox_push_certs/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= link_to 'Your Apps', apps_path %> / <%= link_to @app.name, @app %> 3 | / <%= link_to 'Push Challenges', app_push_notes_path(@app) %> 4 | / Upload Sandbox Push Cert 5 |

6 |
7 | 8 |
9 | <% if @app.sandbox_push_cert %> 10 |
You have already uploaded a sandbox push cert. 11 |
12 | <% else %> 13 | Upload a sandbox push cert: 14 | <%= form_for(@sandbox_push_cert, :url => app_sandbox_push_cert_path) do |f| %> 15 | 16 | <% if @sandbox_push_cert.errors.any? %> 17 |
18 |

<%= pluralize(@sandbox_push_cert.errors.count, "error") %> prohibited the push cert from being saved:

19 | 20 |
    21 | <% @sandbox_push_cert.errors.full_messages.each do |msg| %> 22 |
  • <%= msg %>
  • 23 | <% end %> 24 |
25 |
26 | <% end %> 27 |
28 | <%= f.label :p12, "Sandbox Push Cert in .p12 format:" %> 29 | <%= f.file_field :p12 %> 30 |
31 |
32 | <%= f.label :p12_pw, "Password for .p12 file:" %> 33 | <%= f.password_field :p12_pw %> 34 |
35 | <%= f.submit %> 36 | <% end %> 37 | <% end %> 38 |
39 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/sandbox_push_certs/test_push.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= link_to 'Your Apps', apps_path %> / <%= link_to @app.name, @app %> 3 | / <%= link_to 'Push Challenges', app_push_notes_path(@app) %> 4 | / Send Test Push 5 |

6 |
7 | 8 |
1. Download this <%= link_to 'test app', app_sandbox_test_project_path(@app) %>. 9 | Based on your push certificate, the bundle identifier in the test app has been set to <%= @app.sandbox_push_cert.bundle_identifier %> 10 |
11 | 12 |
13 | 2. Build and run the test app on your iPhone. If all goes well a push token will be logged to the console. 14 |
15 | 16 |
17 | 3. Copy the token from console and close the app. 18 |
19 | 20 |
21 | 4. Paste the token here and send a message to yourself! 22 |
23 | 24 |
25 | 26 | 27 | <%= form_tag(app_sandbox_test_push_path(@app), :method => :post) do %> 28 |
29 | <%= label_tag :token, "Token:" %> 30 | <%= text_field_tag :token, @token, {:size => 100}%> 31 |
32 |
33 | <%= label_tag :body, "Push Body:" %> 34 | <%= text_field_tag :body, '', {:size => 50} %> 35 |
36 |
37 | <%= submit_tag("Send it!") %> 38 |
39 | <% end %> 40 | -------------------------------------------------------------------------------- /dashboard/app/views/dashboard/turns/new.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for @turn, :url => :turns, :html => { :multipart => true } do |f| %> 2 | 3 | 4 |
5 | <%= f.label :meta_doc %> 6 | <%= f.file_field :meta_doc %> 7 |
8 | 9 |
10 | <%= f.label :uuid %> 11 | <%= f.text_field :uuid %> 12 |
13 | 14 |
15 | <%= f.label :user_id %> 16 | <%= f.text_field :user_id %> 17 |
18 | 19 |
20 | <%= f.submit %> 21 |
22 | <% end %> 23 | -------------------------------------------------------------------------------- /dashboard/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /dashboard/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /dashboard/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /dashboard/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run OKDashboard::Application 5 | -------------------------------------------------------------------------------- /dashboard/config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /dashboard/config/database.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: mysql2 3 | encoding: utf8 4 | database: leaderboard_dev 5 | username: root 6 | password: 7 | host: localhost 8 | port: 3306 9 | 10 | # Warning: The database defined as "test" will be erased and 11 | # re-generated from your development database when you run "rake". 12 | # Do not set this db to the same as development or production. 13 | # Ensure the SQLite 3 gem is defined in your Gemfile 14 | # gem 'sqlite3' 15 | test: 16 | adapter: mysql2 17 | encoding: utf8 18 | database: leaderboard_test 19 | host: 127.0.0.1 20 | port: 3306 21 | 22 | production: 23 | adapter: mysql2 24 | encoding: utf8 25 | database: <%= OKConfig[:database_name] %> 26 | username: <%= OKConfig[:database_username] %> 27 | password: <%= OKConfig[:database_password] %> 28 | host: <%= OKConfig[:database_host] %> 29 | port: <%= OKConfig[:database_port] %> 30 | -------------------------------------------------------------------------------- /dashboard/config/deploy.rb: -------------------------------------------------------------------------------- 1 | set :application, 'openkit' 2 | set :repo_url, 'git@github.com:OpenKit/openkit-server.git' 3 | set :deploy_to, "/var/www/#{fetch(:application)}" 4 | set :git_strategy, GitStrategy 5 | set :subdir, 'dashboard' 6 | set :branch, 'lzell-provisioning' 7 | 8 | set :ssh_options, { 9 | keys: %w(~/.ssh/openkit.pub), 10 | user: 'ec2-user', 11 | forward_agent: true, 12 | auth_methods: %w(publickey) 13 | } 14 | 15 | set :log_level, :debug # :info 16 | set :pty, true 17 | set :format, :pretty 18 | 19 | set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system} 20 | 21 | set :keep_releases, 10 22 | 23 | # ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp } 24 | # set :default_env, { path: "/opt/ruby/bin:$PATH" } 25 | 26 | namespace :deploy do 27 | after :finishing, 'deploy:cleanup' 28 | after :finishing, 'unicorn:upgrade' 29 | end 30 | -------------------------------------------------------------------------------- /dashboard/config/deploy/production.rb: -------------------------------------------------------------------------------- 1 | set :stage, :production 2 | 3 | # Dynamically set these from openkit config 4 | app_ip = '54.184.19.198' 5 | db_ip = '10.0.0.1' 6 | 7 | server app_ip, roles: %w{web app}, node_label: :prod_app1 8 | server db_ip, roles: %w{db}, node_label: :prod_db1 9 | -------------------------------------------------------------------------------- /dashboard/config/deploy/staging.rb: -------------------------------------------------------------------------------- 1 | set :stage, :staging 2 | 3 | # Dynamically set these from openkit config 4 | app_ip = '54.184.19.198' 5 | db_ip = '10.0.0.1' 6 | 7 | server app_ip, roles: %w{web app}, node_label: :staging_app1 8 | server db_ip, roles: %w{db}, node_label: :staging_db1 9 | -------------------------------------------------------------------------------- /dashboard/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | OKDashboard::Application.initialize! 6 | -------------------------------------------------------------------------------- /dashboard/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | OKDashboard::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Disable full error reports 13 | config.consider_all_requests_local = false 14 | 15 | # Disable caching 16 | config.action_controller.perform_caching = false 17 | 18 | # Don't care if the mailer can't send 19 | config.action_mailer.raise_delivery_errors = false 20 | 21 | # Print deprecation notices to the Rails logger 22 | config.active_support.deprecation = :log 23 | 24 | # Raise an error on page load if there are pending migrations 25 | config.active_record.migration_error = :page_load 26 | 27 | # Debug mode disables concatenation and preprocessing of assets. 28 | # This option may cause significant delays in view rendering with a large 29 | # number of complex assets. 30 | config.assets.debug = true 31 | 32 | # Quiet asset logging in development, also applied this patch to webrick: 33 | # https://bugs.ruby-lang.org/attachments/2300/204_304_keep_alive.patch 34 | # which prevents, "WARN could not determine content-length of response body" warning. 35 | # config.assets.debug = false 36 | # config.assets.logger = false 37 | end 38 | -------------------------------------------------------------------------------- /dashboard/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | OKDashboard::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static asset server for tests with Cache-Control for performance. 16 | config.serve_static_assets = true 17 | config.static_cache_control = "public, max-age=3600" 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Print deprecation notices to the stderr. 35 | config.active_support.deprecation = :stderr 36 | end 37 | -------------------------------------------------------------------------------- /dashboard/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /dashboard/config/initializers/custom_initializer.rb: -------------------------------------------------------------------------------- 1 | require 'random_gen' 2 | require 'ok_redis' 3 | require 'paperclip_helper.rb' 4 | require 'two_legged_oauth' 5 | require 'feature_array.rb' 6 | require 'apple_push/apple_push.rb' 7 | require 'push_test_project.rb' 8 | require 'push_queue.rb' 9 | 10 | 11 | module ActiveModel 12 | class Errors 13 | 14 | def merge!(errors, options={}) 15 | fields_to_merge = if only=options[:only] 16 | only 17 | elsif except=options[:except] 18 | except = [except] unless except.is_a?(Array) 19 | except.map!(&:to_sym) 20 | errors.entries.map(&:first).select do |field| 21 | !except.include?(field.to_sym) 22 | end 23 | else 24 | errors.entries.map(&:first) 25 | end 26 | fields_to_merge = [fields_to_merge] unless fields_to_merge.is_a?(Array) 27 | fields_to_merge.map!(&:to_sym) 28 | 29 | errors.entries.each do |field, msg| 30 | add field, msg if fields_to_merge.include?(field.to_sym) 31 | end 32 | end 33 | end 34 | end 35 | 36 | if OKConfig[:s3_attachment_bucket] 37 | Paperclip::Attachment.default_options[:url] = ':s3_domain_url' 38 | Paperclip::Attachment.default_options[:path] = '/:class/:attachment/:id_partition/:style/:filename' 39 | end 40 | 41 | -------------------------------------------------------------------------------- /dashboard/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /dashboard/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /dashboard/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /dashboard/config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure your secret_key_base is kept private 11 | # if you're sharing your code publicly. 12 | OKDashboard::Application.config.secret_key_base = OKConfig[:rails_secret_token] 13 | -------------------------------------------------------------------------------- /dashboard/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | OKDashboard::Application.config.session_store :cookie_store, key: OKConfig[:rails_session_store_key] 4 | -------------------------------------------------------------------------------- /dashboard/config/initializers/setup_mail.rb: -------------------------------------------------------------------------------- 1 | ActionMailer::Base.smtp_settings = { 2 | :address => "smtp.gmail.com", 3 | :port => 587, 4 | :domain => OKConfig[:mail_domain], 5 | :user_name => OKConfig[:mail_user], 6 | :password => OKConfig[:mail_pass], 7 | :authentication => "plain", 8 | :enable_starttls_auto => true 9 | } 10 | 11 | mailer_host = OKConfig[:mailer_host] 12 | ActionMailer::Base.default_url_options[:host] = mailer_host 13 | # Mail.register_interceptor(DevelopmentMailInterceptor) if Rails.env.development? 14 | -------------------------------------------------------------------------------- /dashboard/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /dashboard/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /dashboard/config/ok_config.rb: -------------------------------------------------------------------------------- 1 | module OKConfig 2 | extend self 3 | 4 | def config_hash 5 | @config_hash ||= begin 6 | { 7 | :database_name => nil || 'ok_api', 8 | :database_username => nil || 'root', 9 | :database_password => nil || '', 10 | :database_host => nil || '127.0.0.1', 11 | :database_port => nil || '3306', 12 | :redis_host => nil || '127.0.0.1', 13 | :redis_port => nil || '6379', 14 | :mail_domain => nil || 'www.example.com', 15 | :mail_user => nil || 'no-reply@www.example.com', 16 | :mail_pass => nil || 'replaceme', 17 | :mailer_host => nil || 'www.example.com', 18 | :aws_key => nil || ENV['AWS_ACCESS_KEY_ID'] || 'public-aws-key', 19 | :aws_secret => nil || ENV['AWS_SECRET_ACCESS_KEY'] || 'signing-key', 20 | :s3_attachment_bucket => nil || ENV['OK_S3_ATTACHMENT_BUCKET'], 21 | :rails_secret_token => nil || '15a4c101b9dc5a9eb0a95b81a983aa0a3ffb58c4dc910ca102a226402f39349c8cb267a6ac90371459001ad7aabab99a85ce5ba23f30abc55471f6ef788e972f', 22 | :rails_session_store_key => nil || '_openkit_session', 23 | :apns_host => nil || 'gateway.push.apple.com', 24 | :apns_pem_path => nil || '/var/openkit/apple_certs/production', 25 | :apns_sandbox_host => nil || 'gateway.sandbox.push.apple.com', 26 | :apns_sandbox_pem_path => nil || '/var/openkit/apple_certs/sandbox', 27 | } 28 | end 29 | end 30 | 31 | def [](k) 32 | config_hash[k] 33 | end 34 | end 35 | 36 | -------------------------------------------------------------------------------- /dashboard/custom_plan.rb: -------------------------------------------------------------------------------- 1 | require 'zeus/rails' 2 | 3 | # Overriding the test method for a couple reason: 4 | # 5 | # 1. We don't want to fall back to rake if arguments are not supplied. 6 | # That is, 'zeus t' should run all tests without involving rake. 7 | # 8 | # 2. 'rails/test_help', which is required by dashboard/test/test_helper.rb, 9 | # eventually calls MiniTest::Unit.autorun. The default Zeus test 10 | # implementation uses Zeus::M.run to explicitly run tests. This led to 11 | # tests running twice. 12 | # 13 | class CustomPlan < Zeus::Rails 14 | 15 | # See lib/zeus/rails.rb in the Zeus gem to see default behavior. 16 | def test(argv=ARGV) 17 | if argv.empty? 18 | Dir[Rails.root.join("test/**/*_test.rb")].each {|f| require f} 19 | else 20 | argv.each {|f| require f} 21 | end 22 | end 23 | 24 | end 25 | 26 | Zeus.plan = CustomPlan.new 27 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121211232400_create_leaderboards.rb: -------------------------------------------------------------------------------- 1 | class CreateLeaderboards < ActiveRecord::Migration 2 | def change 3 | create_table :leaderboards do |t| 4 | t.string :name 5 | t.references :game 6 | 7 | t.timestamps 8 | end 9 | add_index :leaderboards, :game_id 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121212003310_create_apps.rb: -------------------------------------------------------------------------------- 1 | class CreateApps < ActiveRecord::Migration 2 | def change 3 | create_table :apps do |t| 4 | t.string :name 5 | t.references :developer 6 | 7 | t.timestamps 8 | end 9 | add_index :apps, :developer_id 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121213235802_rename_games_applications.rb: -------------------------------------------------------------------------------- 1 | class RenameGamesApplications < ActiveRecord::Migration 2 | def up 3 | rename_table :apps, :applications 4 | rename_column :leaderboards, :game_id, :application_id 5 | end 6 | 7 | def down 8 | rename_column :leaderboards, :application_id, :game_id 9 | rename_table :applications, :apps 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121214010230_create_developers.rb: -------------------------------------------------------------------------------- 1 | class CreateDevelopers < ActiveRecord::Migration 2 | def change 3 | create_table :developers do |t| 4 | t.string :name 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121214012407_rename_applications_apps.rb: -------------------------------------------------------------------------------- 1 | class RenameApplicationsApps < ActiveRecord::Migration 2 | def up 3 | rename_table :applications, :apps 4 | rename_column :leaderboards, :application_id, :app_id 5 | end 6 | 7 | def down 8 | rename_column :leaderboards, :app_id, :application_id 9 | rename_table :apps, :applications 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121214041237_add_authlogic_field_to_developers.rb: -------------------------------------------------------------------------------- 1 | class AddAuthlogicFieldToDevelopers < ActiveRecord::Migration 2 | def change 3 | add_column :developers, :email, :string 4 | add_column :developers, :crypted_password, :string 5 | add_column :developers, :password_salt, :string 6 | add_column :developers, :persistence_token, :string 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121214044630_add_slug_to_apps.rb: -------------------------------------------------------------------------------- 1 | class AddSlugToApps < ActiveRecord::Migration 2 | def change 3 | add_column :apps, :slug, :string 4 | add_index :apps, :slug, unique: true 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121214054142_remove_unique_from_app_slug.rb: -------------------------------------------------------------------------------- 1 | class RemoveUniqueFromAppSlug < ActiveRecord::Migration 2 | def up 3 | remove_index :apps, :column => ["slug"] 4 | add_index :apps, ["developer_id", "slug"] 5 | end 6 | 7 | def down 8 | remove_index :apps, :column => ["developer_id", "slug"] 9 | add_index :apps, ["slug"], :unique => true 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121214104910_add_attachment_icon_header_image_to_leaderboards.rb: -------------------------------------------------------------------------------- 1 | class AddAttachmentIconHeaderImageToLeaderboards < ActiveRecord::Migration 2 | def self.up 3 | change_table :leaderboards do |t| 4 | t.has_attached_file :icon 5 | t.has_attached_file :header_image 6 | end 7 | end 8 | 9 | def self.down 10 | drop_attached_file :leaderboards, :icon 11 | drop_attached_file :leaderboards, :header_image 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121214204641_add_in_development_to_leaderboards.rb: -------------------------------------------------------------------------------- 1 | class AddInDevelopmentToLeaderboards < ActiveRecord::Migration 2 | def change 3 | add_column :leaderboards, :in_development, :boolean, :default => true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121215012621_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table :users do |t| 4 | t.string :nick 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121215055142_add_type_column_to_leaderboards.rb: -------------------------------------------------------------------------------- 1 | class AddTypeColumnToLeaderboards < ActiveRecord::Migration 2 | def change 3 | add_column :leaderboards, :type, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121215073551_create_scores.rb: -------------------------------------------------------------------------------- 1 | class CreateScores < ActiveRecord::Migration 2 | def change 3 | create_table :scores do |t| 4 | t.float :value 5 | t.references :user 6 | t.references :leaderboard 7 | 8 | t.timestamps 9 | end 10 | add_index :scores, :user_id 11 | add_index :scores, :leaderboard_id 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121222210457_add_app_key_to_apps.rb: -------------------------------------------------------------------------------- 1 | class AddAppKeyToApps < ActiveRecord::Migration 2 | def change 3 | add_column :apps, :app_key, :string, :limit => 20 4 | add_index :apps, [:app_key], :unique => true 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121224195721_add_developer_id_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddDeveloperIdToUsers < ActiveRecord::Migration 2 | def change 3 | add_column :users, :developer_id, :integer 4 | add_index "users", ["developer_id"], :name => "index_users_on_developer_id" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121224201402_create_subscriptions.rb: -------------------------------------------------------------------------------- 1 | class CreateSubscriptions < ActiveRecord::Migration 2 | def change 3 | create_table :subscriptions do |t| 4 | t.references :app 5 | t.references :user 6 | 7 | t.timestamps 8 | end 9 | add_index :subscriptions, :app_id 10 | add_index :subscriptions, :user_id 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121226022857_drop_attached_header_from_leaderboards.rb: -------------------------------------------------------------------------------- 1 | class DropAttachedHeaderFromLeaderboards < ActiveRecord::Migration 2 | def up 3 | drop_attached_file :leaderboards, :header_image 4 | change_table :apps do |t| 5 | t.has_attached_file :header_image 6 | end 7 | end 8 | 9 | def down 10 | drop_attached_file :apps, :header_image 11 | change_table :leaderboards do |t| 12 | t.has_attached_file :header_image 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121226023835_add_icon_to_apps.rb: -------------------------------------------------------------------------------- 1 | class AddIconToApps < ActiveRecord::Migration 2 | def up 3 | change_table :apps do |t| 4 | t.has_attached_file :icon 5 | end 6 | end 7 | 8 | def down 9 | drop_attached_file :apps, :icon 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20121228191043_drop_sti_from_leaderboards.rb: -------------------------------------------------------------------------------- 1 | class DropStiFromLeaderboards < ActiveRecord::Migration 2 | def up 3 | remove_column :leaderboards, :type 4 | add_column :leaderboards, :sort_type, :string, :limit => 20 5 | end 6 | 7 | def down 8 | remove_column :leaderboards, :sort_type 9 | add_column :leaderboards, :type, :string 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130102201852_add_perishable_token_to_developers.rb: -------------------------------------------------------------------------------- 1 | class AddPerishableTokenToDevelopers < ActiveRecord::Migration 2 | def up 3 | add_column :developers, :perishable_token, :string, :default => "", :null => false 4 | add_index :developers, [:perishable_token] 5 | end 6 | 7 | def down 8 | remove_index :developers, :column => [:perishable_token] 9 | remove_column :developers, :perishable_token 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130104032036_create_delayed_jobs.rb: -------------------------------------------------------------------------------- 1 | class CreateDelayedJobs < ActiveRecord::Migration 2 | def self.up 3 | create_table :delayed_jobs, :force => true do |table| 4 | table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue 5 | table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually. 6 | table.text :handler # YAML-encoded string of the object that will do work 7 | table.text :last_error # reason for last failure (See Note below) 8 | table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. 9 | table.datetime :locked_at # Set when a client is working on this object 10 | table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) 11 | table.string :locked_by # Who is working on this object (if locked) 12 | table.string :queue # The name of the queue this job is in 13 | table.timestamps 14 | end 15 | 16 | add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority' 17 | end 18 | 19 | def self.down 20 | drop_table :delayed_jobs 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130104064711_add_fb_id_and_twitter_id_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddFbIdAndTwitterIdToUsers < ActiveRecord::Migration 2 | def up 3 | add_column :users, :twitter_id, 'bigint UNSIGNED' 4 | add_column :users, :fb_id, 'bigint UNSIGNED' 5 | 6 | add_index :users, [:twitter_id] 7 | add_index :users, [:fb_id] 8 | end 9 | 10 | def down 11 | remove_index :users, :column => [:fb_id] 12 | remove_index :users, :column => [:twitter_id] 13 | 14 | remove_column :users, :fb_id 15 | remove_column :users, :twitter_id 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130121094006_specify_precision_on_floats.rb: -------------------------------------------------------------------------------- 1 | class SpecifyPrecisionOnFloats < ActiveRecord::Migration 2 | def up 3 | change_column :scores, :value, :decimal, :precision => 16, :scale => 2 4 | end 5 | 6 | def down 7 | change_column :scores, :value, :float 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130131234141_add_composite_index_on_scores.rb: -------------------------------------------------------------------------------- 1 | class AddCompositeIndexOnScores < ActiveRecord::Migration 2 | def up 3 | add_index :scores, [:leaderboard_id, :user_id, :value] 4 | end 5 | 6 | def down 7 | remove_index :scores, :column => [:leaderboard_id, :user_id, :value] 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130206025130_drop_header_from_apps.rb: -------------------------------------------------------------------------------- 1 | class DropHeaderFromApps < ActiveRecord::Migration 2 | def up 3 | drop_attached_file :apps, :header_image 4 | end 5 | 6 | def down 7 | change_table :apps do |t| 8 | t.has_attached_file :header_image 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130412231348_add_metadata_to_base_score.rb: -------------------------------------------------------------------------------- 1 | class AddMetadataToBaseScore < ActiveRecord::Migration 2 | def up 3 | add_column :scores, :metadata, :integer 4 | add_column :best_scores, :metadata, :integer 5 | add_column :best_scores_1, :metadata, :integer 6 | add_column :best_scores_7, :metadata, :integer 7 | end 8 | def down 9 | remove_column :scores, :metadata 10 | remove_column :best_scores, :metadata 11 | remove_column :best_scores_1, :metadata 12 | remove_column :best_scores_7, :metadata 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130416004410_add_display_string_to_scores.rb: -------------------------------------------------------------------------------- 1 | class AddDisplayStringToScores < ActiveRecord::Migration 2 | def up 3 | rename_column :scores, :display_value, :display_string 4 | add_column :best_scores, :display_string, :string 5 | add_column :best_scores_1, :display_string, :string 6 | add_column :best_scores_7, :display_string, :string 7 | end 8 | def down 9 | rename_column :scores, :display_string, :display_value 10 | remove_column :best_scores, :display_string 11 | remove_column :best_scores_1, :display_string 12 | remove_column :best_scores_7, :display_string 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130416225733_make_scores_big_ints.rb: -------------------------------------------------------------------------------- 1 | class MakeScoresBigInts < ActiveRecord::Migration 2 | def up 3 | change_column :scores, :value, 'bigint SIGNED' 4 | change_column :best_scores, :value, 'bigint SIGNED' 5 | change_column :best_scores_1, :value, 'bigint SIGNED' 6 | change_column :best_scores_7, :value, 'bigint SIGNED' 7 | end 8 | 9 | def down 10 | change_column :scores, :value, :integer 11 | change_column :best_scores, :value, :integer 12 | change_column :best_scores_1, :value, :integer 13 | change_column :best_scores_7, :value, :integer 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130417023019_rename_value_to_sort_value.rb: -------------------------------------------------------------------------------- 1 | class RenameValueToSortValue < ActiveRecord::Migration 2 | def up 3 | rename_column :scores, :value, :sort_value 4 | end 5 | 6 | def down 7 | rename_column :scores, :sort_value, :value 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130417232335_create_achievements.rb: -------------------------------------------------------------------------------- 1 | class CreateAchievements < ActiveRecord::Migration 2 | def change 3 | create_table "achievements", :force => true do |t| 4 | t.string "name" 5 | t.integer "app_id" 6 | t.datetime "created_at", :null => false 7 | t.datetime "updated_at", :null => false 8 | t.string "icon_locked_file_name" 9 | t.string "icon_locked_content_type" 10 | t.integer "icon_locked_file_size" 11 | t.datetime "icon_locked_updated_at" 12 | t.string "icon_file_name" 13 | t.string "icon_content_type" 14 | t.integer "icon_file_size" 15 | t.datetime "icon_updated_at" 16 | t.boolean "in_development", :default => true 17 | end 18 | 19 | add_index "achievements", ["app_id"], :name => "index_achievements_on_game_id" 20 | 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130417235451_add_desc_to_achievements.rb: -------------------------------------------------------------------------------- 1 | class AddDescToAchievements < ActiveRecord::Migration 2 | def change 3 | add_column :achievements, :desc, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130418021336_add_points_to_achievements.rb: -------------------------------------------------------------------------------- 1 | class AddPointsToAchievements < ActiveRecord::Migration 2 | def change 3 | add_column :achievements, :points, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130418021401_add_goal_to_achievements.rb: -------------------------------------------------------------------------------- 1 | class AddGoalToAchievements < ActiveRecord::Migration 2 | def change 3 | add_column :achievements, :goal, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130418150745_add_custom_id_to_ok_users.rb: -------------------------------------------------------------------------------- 1 | class AddCustomIdToOkUsers < ActiveRecord::Migration 2 | def change 3 | add_column :users, :custom_id, 'bigint UNSIGNED' 4 | add_index :users, :custom_id, :name => "index_users_on_custom_id" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130420180955_create_achievement_progress.rb: -------------------------------------------------------------------------------- 1 | class CreateAchievementProgress < ActiveRecord::Migration 2 | def change 3 | create_table "achievement_progress", :force => true do |t| 4 | t.integer "app_id" 5 | t.integer "user_id" 6 | t.integer "achievement_id" 7 | t.integer "progress" 8 | t.datetime "created_at", :null => false 9 | end 10 | 11 | add_index "achievement_progress", ["app_id", "user_id", "achievement_id"], :name => "index_achievement_progress_on_app_user_and_achievement_id" 12 | add_index "achievement_progress", ["app_id", "user_id"], :name => "index_achievement_progress_on_app_and_user_id" 13 | 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130423235151_rename_achievement_progress.rb: -------------------------------------------------------------------------------- 1 | class RenameAchievementProgress < ActiveRecord::Migration 2 | def up 3 | rename_table :achievement_progress, :achievement_scores 4 | end 5 | 6 | def down 7 | rename_table :achievement_scores, :achievement_progress 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130425202438_remove_appid_from_achievement_scores.rb: -------------------------------------------------------------------------------- 1 | class RemoveAppidFromAchievementScores < ActiveRecord::Migration 2 | def up 3 | remove_column :achievement_scores, :app_id 4 | end 5 | 6 | def down 7 | add_column :achievement_scores, :app_id 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130426174146_add_fbid_to_apps.rb: -------------------------------------------------------------------------------- 1 | class AddFbidToApps < ActiveRecord::Migration 2 | def change 3 | add_column :apps, :fbid, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130426221939_achievements_touchup.rb: -------------------------------------------------------------------------------- 1 | class AchievementsTouchup < ActiveRecord::Migration 2 | def up 3 | remove_index 'achievements', :name => 'index_achievements_on_game_id' 4 | add_index 'achievements', ['app_id'], :name => 'index_achievements_on_app_id' 5 | end 6 | 7 | def down 8 | remove_index 'achievements', :name => 'index_achievements_on_app_id' 9 | add_index 'achievements', ['app_id'], :name => 'index_achievements_on_game_id' 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130430072017_create_oauth_tables.rb: -------------------------------------------------------------------------------- 1 | class CreateOauthTables < ActiveRecord::Migration 2 | def self.up 3 | create_table :client_applications do |t| 4 | t.string :name 5 | t.string :url 6 | t.string :support_url 7 | t.string :callback_url 8 | t.string :key, :limit => 40 9 | t.string :secret, :limit => 40 10 | t.integer :user_id 11 | 12 | t.timestamps 13 | end 14 | add_index :client_applications, :key, :unique => true 15 | 16 | create_table :oauth_tokens do |t| 17 | t.integer :user_id 18 | t.string :type, :limit => 20 19 | t.integer :client_application_id 20 | t.string :token, :limit => 40 21 | t.string :secret, :limit => 40 22 | t.string :callback_url 23 | t.string :verifier, :limit => 20 24 | t.string :scope 25 | t.timestamp :authorized_at, :invalidated_at, :expires_at 26 | t.timestamps 27 | end 28 | 29 | add_index :oauth_tokens, :token, :unique => true 30 | 31 | create_table :oauth_nonces do |t| 32 | t.string :nonce 33 | t.integer :timestamp 34 | 35 | t.timestamps 36 | end 37 | add_index :oauth_nonces,[:nonce, :timestamp], :unique => true 38 | 39 | end 40 | 41 | def self.down 42 | drop_table :client_applications 43 | drop_table :oauth_tokens 44 | drop_table :oauth_nonces 45 | end 46 | 47 | end 48 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130430215726_drop_oauth_plugin_tables.rb: -------------------------------------------------------------------------------- 1 | class DropOauthPluginTables < ActiveRecord::Migration 2 | def up 3 | # Keep nonces, we need those. 4 | drop_table :oauth_tokens 5 | drop_table :client_applications 6 | end 7 | 8 | def down 9 | create_table :client_applications do |t| 10 | t.string :name 11 | t.string :url 12 | t.string :support_url 13 | t.string :callback_url 14 | t.string :key, :limit => 40 15 | t.string :secret, :limit => 40 16 | t.integer :user_id 17 | 18 | t.timestamps 19 | end 20 | add_index :client_applications, :key, :unique => true 21 | 22 | create_table :oauth_tokens do |t| 23 | t.integer :user_id 24 | t.string :type, :limit => 20 25 | t.integer :client_application_id 26 | t.string :token, :limit => 40 27 | t.string :secret, :limit => 40 28 | t.string :callback_url 29 | t.string :verifier, :limit => 20 30 | t.string :scope 31 | t.timestamp :authorized_at, :invalidated_at, :expires_at 32 | t.timestamps 33 | end 34 | 35 | add_index :oauth_tokens, :token, :unique => true 36 | 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130430220215_add_secret_key_to_apps.rb: -------------------------------------------------------------------------------- 1 | class AddSecretKeyToApps < ActiveRecord::Migration 2 | def change 3 | add_column :apps, :secret_key, :string, :limit => 40 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130502211458_add_google_id_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddGoogleIdToUsers < ActiveRecord::Migration 2 | def change 3 | add_column :users, :google_id, 'bigint UNSIGNED' 4 | add_index :users, :google_id, :name => "index_users_on_google_id" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130613013602_add_gamecenter_id_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddGamecenterIdToUsers < ActiveRecord::Migration 2 | def change 3 | add_column :users, :gamecenter_id, :string 4 | add_index :users, :gamecenter_id, :name => "index_users_on_gamecenter_id" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130613190346_add_game_center_and_google_to_leaderboard.rb: -------------------------------------------------------------------------------- 1 | class AddGameCenterAndGoogleToLeaderboard < ActiveRecord::Migration 2 | def up 3 | add_column :leaderboards, :gamecenter_id, :string 4 | add_column :leaderboards, :gpg_id, :string 5 | end 6 | 7 | def down 8 | remove_column :leaderboards, :gamecenter_id 9 | remove_column :leaderboards, :gpg_id 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130711040819_add_priority_to_leaderboards.rb: -------------------------------------------------------------------------------- 1 | class AddPriorityToLeaderboards < ActiveRecord::Migration 2 | def change 3 | add_column :leaderboards, :priority, :integer, :null => false, :default => 100 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130803170905_add_meta_doc_to_scores.rb: -------------------------------------------------------------------------------- 1 | class AddMetaDocToScores < ActiveRecord::Migration 2 | def up 3 | add_attachment :scores, :meta_doc 4 | end 5 | 6 | def down 7 | remove_attachment :scores, :meta_doc 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130809000348_index_scores_on_sort_value.rb: -------------------------------------------------------------------------------- 1 | class IndexScoresOnSortValue < ActiveRecord::Migration 2 | def up 3 | remove_index "scores", :name => "index_scores_on_leaderboard_id_and_user_id" 4 | 5 | add_index :scores, [:leaderboard_id, :sort_value, :created_at], :order => {:sort_value => :desc}, :name => "index_scores_composite_1" 6 | add_index :scores, [:leaderboard_id, :user_id, :sort_value, :created_at], :order => {:sort_value => :desc}, :name => "index_scores_composite_2" 7 | end 8 | 9 | def down 10 | remove_index :scores, :name => "index_scores_composite_2" 11 | remove_index :scores, :name => "index_scores_composite_1" 12 | 13 | add_index "scores", ["leaderboard_id", "user_id"], :name => "index_scores_on_leaderboard_id_and_user_id" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130826194151_acts_as_taggable_on_migration.rb: -------------------------------------------------------------------------------- 1 | class ActsAsTaggableOnMigration < ActiveRecord::Migration 2 | def self.up 3 | create_table :tags do |t| 4 | t.string :name 5 | end 6 | 7 | create_table :taggings do |t| 8 | t.references :tag 9 | 10 | # You should make sure that the column created is 11 | # long enough to store the required class names. 12 | t.references :taggable, :polymorphic => true 13 | t.references :tagger, :polymorphic => true 14 | 15 | # Limit is created to prevent MySQL error on index 16 | # length for MyISAM table type: http://bit.ly/vgW2Ql 17 | t.string :context, :limit => 128 18 | 19 | t.datetime :created_at 20 | end 21 | 22 | add_index :taggings, :tag_id 23 | add_index :taggings, [:taggable_id, :taggable_type, :context] 24 | end 25 | 26 | def self.down 27 | drop_table :taggings 28 | drop_table :tags 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130829135119_create_client_sessions.rb: -------------------------------------------------------------------------------- 1 | class CreateClientSessions < ActiveRecord::Migration 2 | def change 3 | create_table :client_sessions do |t| 4 | t.string :uuid 5 | t.string :fb_id 6 | t.string :google_id 7 | t.string :custom_id 8 | t.string :ok_id 9 | t.string :push_token 10 | t.string :client_db_version 11 | t.datetime :client_created_at 12 | 13 | t.timestamps 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130829150430_add_app_id_to_client_sessions.rb: -------------------------------------------------------------------------------- 1 | class AddAppIdToClientSessions < ActiveRecord::Migration 2 | def change 3 | add_column :client_sessions, :app_id, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130829152319_create_tokens.rb: -------------------------------------------------------------------------------- 1 | class CreateTokens < ActiveRecord::Migration 2 | def change 3 | create_table :tokens do |t| 4 | t.integer :user_id 5 | t.integer :app_id 6 | t.string :apns_token 7 | t.datetime :created_at, :null => false 8 | end 9 | add_index :tokens, [:user_id, :app_id] 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130911000023_create_api_whitelists.rb: -------------------------------------------------------------------------------- 1 | class CreateApiWhitelists < ActiveRecord::Migration 2 | def change 3 | create_table :api_whitelists do |t| 4 | t.string :app_key 5 | t.string :version, :limit => 5 6 | end 7 | add_index "api_whitelists", ["app_key", "version"] 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130919003718_create_sandbox_scores.rb: -------------------------------------------------------------------------------- 1 | class CreateSandboxScores < ActiveRecord::Migration 2 | def up 3 | create_table "sandbox_scores", :force => true do |t| 4 | t.integer "sort_value", :limit => 8, :null => false 5 | t.integer "user_id" 6 | t.integer "leaderboard_id" 7 | t.datetime "created_at", :null => false 8 | t.string "display_string" 9 | t.integer "metadata" 10 | t.string "meta_doc_file_name" 11 | t.string "meta_doc_content_type" 12 | t.integer "meta_doc_file_size" 13 | t.datetime "meta_doc_updated_at" 14 | end 15 | 16 | add_index "sandbox_scores", ["leaderboard_id", "sort_value", "created_at"], :name => "index_sandbox_scores_composite_1" 17 | add_index "sandbox_scores", ["leaderboard_id", "user_id", "sort_value", "created_at"], :name => "index_sandbox_scores_composite_2" 18 | end 19 | 20 | def down 21 | remove_index "sandbox_scores", :name => "index_sandbox_scores_composite_2" 22 | remove_index "sandbox_scores", :name => "index_sandbox_scores_composite_1" 23 | drop_table "sandbox_scores" 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130919003905_create_sandbox_achievement_scores.rb: -------------------------------------------------------------------------------- 1 | class CreateSandboxAchievementScores < ActiveRecord::Migration 2 | def up 3 | create_table "sandbox_achievement_scores", :force => true do |t| 4 | t.integer "user_id" 5 | t.integer "achievement_id" 6 | t.integer "progress" 7 | t.datetime "created_at", :null => false 8 | end 9 | add_index "sandbox_achievement_scores", ["user_id", "achievement_id"] 10 | add_index "sandbox_achievement_scores", ["user_id"] 11 | end 12 | 13 | def down 14 | remove_index "sandbox_achievement_scores", :column => ["user_id"] 15 | remove_index "sandbox_achievement_scores", :column => ["user_id", "achievement_id"] 16 | drop_table "sandbox_achievement_scores" 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20130924235216_create_sandbox_sessions_and_tokens.rb: -------------------------------------------------------------------------------- 1 | class CreateSandboxSessionsAndTokens < ActiveRecord::Migration 2 | def up 3 | create_table "sandbox_client_sessions", :force => true do |t| 4 | t.string "uuid" 5 | t.string "fb_id" 6 | t.string "google_id" 7 | t.string "custom_id" 8 | t.string "ok_id" 9 | t.string "push_token" 10 | t.string "client_db_version" 11 | t.datetime "client_created_at" 12 | t.datetime "created_at", :null => false 13 | t.datetime "updated_at", :null => false 14 | t.integer "app_id" 15 | end 16 | 17 | create_table "sandbox_tokens", :force => true do |t| 18 | t.integer "user_id" 19 | t.integer "app_id" 20 | t.string "apns_token" 21 | t.datetime "created_at", :null => false 22 | end 23 | add_index "sandbox_tokens", ["user_id", "app_id"] 24 | end 25 | 26 | def down 27 | remove_index "sandbox_tokens", :column => ["user_id", "app_id"] 28 | drop_table "sandbox_tokens" 29 | drop_table "sandbox_client_sessions" 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20131021235134_add_feature_list_to_apps.rb: -------------------------------------------------------------------------------- 1 | class AddFeatureListToApps < ActiveRecord::Migration 2 | def change 3 | add_column :apps, :feature_list, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20131031062709_drop_in_development.rb: -------------------------------------------------------------------------------- 1 | class DropInDevelopment < ActiveRecord::Migration 2 | def up 3 | remove_column :achievements, :in_development 4 | remove_column :leaderboards, :in_development 5 | end 6 | 7 | def down 8 | add_column :leaderboards, :in_development, :boolean, :default => true 9 | add_column :achievements, :in_development, :boolean, :default => true 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20131031154407_create_turns.rb: -------------------------------------------------------------------------------- 1 | class CreateTurns < ActiveRecord::Migration 2 | def up 3 | create_table :turns do |t| 4 | t.string "uuid" 5 | t.integer "user_id" 6 | t.timestamps 7 | end 8 | 9 | add_attachment :turns, :meta_doc 10 | end 11 | 12 | def down 13 | remove_attachment :turns, :meta_doc 14 | 15 | drop_table :turns 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /dashboard/db/migrate/20131212071708_drop_slug_from_apps.rb: -------------------------------------------------------------------------------- 1 | class DropSlugFromApps < ActiveRecord::Migration 2 | def up 3 | remove_index :apps, ["developer_id", "slug"] 4 | remove_column :apps, :slug 5 | end 6 | 7 | def down 8 | add_column :apps, :slug, :string 9 | add_index "apps", ["developer_id", "slug"], name: "index_apps_on_developer_id_and_slug", using: :btree 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/files/OKPushTest/OKPushTest/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // OKPushTest 4 | // 5 | // Created by Louis Zell on 11/9/13. 6 | // Copyright (c) 2013 OpenKit. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /dashboard/files/OKPushTest/OKPushTest/Info-Template.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | {{bundle_id}} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /dashboard/files/OKPushTest/OKPushTest/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // OKPushTest 4 | // 5 | // Created by Louis Zell on 11/9/13. 6 | // Copyright (c) 2013 OpenKit. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /dashboard/lib/apple_push/README.md: -------------------------------------------------------------------------------- 1 | API 2 | ==== 3 | 4 | require './apple_push.rb' 5 | 6 | combined_pem_path = './push_dev.pem' 7 | token = "7263097dd87a783c5d90dfa61ad3df3d17b11428143c788e77c1be4c2d162d38" 8 | payload = {aps: {alert: "la la la la", badge: 0, sound: "default"}, other_meta: 10} 9 | 10 | # High level API 11 | # ---------------- 12 | 13 | ApplePush::Sandbox.deliver(token, payload, combined_pem_path) 14 | 15 | 16 | # Lower level API 17 | # --------------- 18 | 19 | host = 'gateway.sandbox.push.apple.com' 20 | note = ApplePush::Note.new(token, payload) 21 | cxn = ApplePush::Connection.new(host, combined_pem_path) 22 | cxn.write(note.packed) 23 | 24 | 25 | Creating the combined pem file 26 | ============================== 27 | 1. Download your push cert from https://developer.apple.com/account/ios/certificate/certificateList.action 28 | 2. Double click on the downloaded cert (aps_development.cer) to add it to keychain. 29 | 3. Right click on the cert in keychain and export it as push_dev.p12 30 | 4. Convert the exported .p12 to a .pem file with: 31 | `$ openssl pkcs12 -in push_dev.p12 -out push_dev.pem -nodes` 32 | 33 | Author 34 | ====== 35 | Lou Zell @ OpenKit. 36 | If you'd like to contribute, or have feedback, please email me at lou@openkit.io. 37 | 38 | Example 39 | ======= 40 | Send messages to yourself: 41 | 42 | ``` 43 | require './apple_push.rb' 44 | 45 | token = "7263097dd87a783c5d90dfa61ad3df3d17b11428143c788e77c1be4c2d162d38" # use your own token 46 | combined_pem_path = './push_dev.pem' # use your own combined pem file 47 | 48 | while (line = gets.chomp) 49 | payload = {aps: {alert: line}} 50 | ApplePush::Sandbox.deliver(token, payload, combined_pem_path) 51 | end 52 | ``` 53 | -------------------------------------------------------------------------------- /dashboard/lib/apple_push/apple_push.rb: -------------------------------------------------------------------------------- 1 | path = File.dirname(__FILE__) 2 | 3 | require File.join(path, 'apple_push', 'note.rb') 4 | require File.join(path, 'apple_push', 'connection.rb') 5 | require File.join(path, 'apple_push', 'pusher.rb') 6 | -------------------------------------------------------------------------------- /dashboard/lib/apple_push/apple_push/connection.rb: -------------------------------------------------------------------------------- 1 | require 'socket' 2 | require 'openssl' 3 | 4 | module ApplePush 5 | class Connection 6 | def initialize(host, combined_pem_path) 7 | @host = host 8 | @combined_pem_path = combined_pem_path 9 | connect() 10 | end 11 | 12 | def send_push(note) 13 | write(note.packed) 14 | end 15 | 16 | def write(x) 17 | ssl_socket.write(x) 18 | ssl_socket.flush() 19 | end 20 | 21 | def disconnect 22 | ssl_socket.close() 23 | end 24 | 25 | private 26 | def connect() 27 | ssl_socket.connect() 28 | end 29 | 30 | def ssl_socket 31 | @ssl_socket ||= OpenSSL::SSL::SSLSocket.new(TCPSocket.new(@host, 2195), context) 32 | end 33 | 34 | def context 35 | @context ||= begin 36 | cert_and_key = File.read(@combined_pem_path) 37 | context = OpenSSL::SSL::SSLContext.new 38 | context.cert = OpenSSL::X509::Certificate.new(cert_and_key) 39 | context.key = OpenSSL::PKey::RSA.new(cert_and_key) 40 | context 41 | end 42 | @context 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /dashboard/lib/apple_push/apple_push/note.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | module ApplePush 4 | class Note 5 | def initialize(token, payload) 6 | @token = token 7 | @payload = payload 8 | end 9 | 10 | def packed 11 | pt = [@token].pack('H*') 12 | pm = @payload.to_json 13 | [0, 0, 32, pt, 0, pm.size, pm].pack("ccca*cca*") 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /dashboard/lib/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/lib/assets/.gitkeep -------------------------------------------------------------------------------- /dashboard/lib/capistrano/git_strategy.rb: -------------------------------------------------------------------------------- 1 | # Patch the git:release task to enable archiving of a repo subdirectory 2 | require 'capistrano/git' 3 | 4 | module GitStrategy 5 | include ::Capistrano::Git::DefaultStrategy 6 | def release 7 | git :archive, archive_argument, '| tar -x -C', release_path 8 | end 9 | 10 | private 11 | def archive_argument 12 | x = fetch(:branch) || "master" 13 | if y = fetch(:subdir) 14 | x = "#{x}:#{y}" 15 | end 16 | x 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /dashboard/lib/capistrano/log_invocations.rb: -------------------------------------------------------------------------------- 1 | require 'colorize' 2 | 3 | module LogInvocations 4 | def self.enable 5 | ::Rake.application.tasks.each do |t| 6 | t.enhance { puts "--- Capistrano Invoking: #{t.name}".magenta } 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/lib/capistrano/tasks/bundler_mysql_install.cap: -------------------------------------------------------------------------------- 1 | namespace :bundler do 2 | before :install, 'bundler:set_mysql_dirs' 3 | task :set_mysql_dirs do 4 | on roles(:app) do 5 | execute "bundle config build.mysql2 --with-mysql-config=/usr/lib/mysql/mysql_config" 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /dashboard/lib/capistrano/tasks/unicorn_helper.rb: -------------------------------------------------------------------------------- 1 | module UnicornHelper 2 | # Putting a within block here doesn't work; I'm not sure why. 3 | # Using an old-fashioned cd in the execute line. 4 | def clean_start(rails_env) 5 | execute "cd #{current_path}; bundle exec unicorn_rails -c config/unicorn.conf.rb -D -E #{rails_env}" 6 | end 7 | 8 | def file_exists?(f) 9 | test("[ -e #{f} ]") 10 | end 11 | 12 | def contents_of(file) 13 | return nil unless file_exists?(file) 14 | capture :cat, file 15 | end 16 | 17 | def kill(pid, signal) 18 | begin 19 | execute :kill, "-s #{signal}", pid 20 | info "Sent #{signal}" 21 | rescue => e 22 | error "Something went wrong: #{e}" 23 | end 24 | end 25 | end 26 | 27 | -------------------------------------------------------------------------------- /dashboard/lib/color_print.rb: -------------------------------------------------------------------------------- 1 | module ColorPrint 2 | def color(msg, code) 3 | printf "\e[#{code}m#{msg}\e[0m\n" 4 | end 5 | 6 | def yellow(msg); color(msg, 33); end 7 | def blue(msg); color(msg, 34); end 8 | def red(msg); color(msg, 31); end 9 | end 10 | -------------------------------------------------------------------------------- /dashboard/lib/feature_array.rb: -------------------------------------------------------------------------------- 1 | class FeatureArray < Array 2 | def <<(obj) 3 | raise StandardError.new("This operation is not supported") 4 | end 5 | end -------------------------------------------------------------------------------- /dashboard/lib/ok_redis.rb: -------------------------------------------------------------------------------- 1 | =begin 2 | 3 | Example usage: 4 | 5 | OKRedis.set "foo", "bar" 6 | OKRedis.get "foo" # => "bar" 7 | 8 | OKRedis.hmset "my_key", "field1", "foo", "field2", "bar" 9 | OKRedis.hget "my_key", "field1" # => "foo" 10 | OKRedis.hgetall "my_key" # => {"field1"=>"foo", "field2"=>"bar"} 11 | 12 | =end 13 | require 'redis' 14 | 15 | module OKRedis 16 | extend self 17 | 18 | def connection 19 | @connection ||= ::Redis.new(:driver => :hiredis, :host => OKConfig[:redis_host], :port => OKConfig[:redis_port]) 20 | end 21 | 22 | def method_missing(sym, *args, &block) 23 | if connection.respond_to? sym 24 | return connection.send(sym, *args, &block) 25 | end 26 | super(sym, *args, &block) 27 | end 28 | 29 | def respond_to_missing?(method, *) 30 | connection.respond_to?(method) || super 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /dashboard/lib/paperclip_helper.rb: -------------------------------------------------------------------------------- 1 | module PaperclipHelper 2 | class << self 3 | def uri_for(obj, base_uri) 4 | if Paperclip::Attachment.default_options[:url] == ':s3_domain_url' 5 | obj.url 6 | else 7 | base_uri + obj.url 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /dashboard/lib/push_loop.rb: -------------------------------------------------------------------------------- 1 | # 2 | # $ bundle exec ruby lib/push_loop.rb 3 | # 4 | require 'thread' 5 | begin 6 | require 'fastthread' 7 | rescue LoadError 8 | end 9 | 10 | 11 | path = File.expand_path(File.dirname(__FILE__)) 12 | require File.join(path, '..', 'config', 'ok_config.rb') 13 | require File.join(path, 'ok_redis.rb') 14 | require File.join(path, 'apple_push', 'apple_push.rb') 15 | 16 | 17 | class PushLoop 18 | 19 | def log(x) 20 | $stdout.puts x 21 | $stdout.flush 22 | end 23 | 24 | def run 25 | log "starting..." 26 | 27 | k = 'pn_queue_2' 28 | while 1 29 | entry = OKRedis.brpop(k) 30 | log "push_thread: Popped a push entry: #{entry}" 31 | pem_path, token, payload, in_sandbox = JSON.parse(entry[1]) 32 | 33 | # Make sure this is a sane push 34 | if pem_path.is_a?(String) && !pem_path.empty? && token.is_a?(String) && token.length == 64 && payload.is_a?(Hash) && payload.has_key?('aps') 35 | log "push_thread: Sending - pem_path: #{pem_path}, Token: #{token}, Payload: #{payload.inspect}" 36 | if in_sandbox 37 | puts '------sending to sandbox' 38 | ApplePush::Sandbox.deliver(token, payload, pem_path) 39 | else 40 | puts '------sending to production' 41 | ApplePush::Production.deliver(token, payload, pem_path) 42 | end 43 | end 44 | end 45 | end 46 | end 47 | 48 | PushLoop.new.run 49 | -------------------------------------------------------------------------------- /dashboard/lib/push_queue.rb: -------------------------------------------------------------------------------- 1 | class PushQueue 2 | class << self 3 | def add(pem_path, token, payload, in_sandbox) 4 | if token.length == 64 5 | entry = [pem_path, token, payload, in_sandbox] 6 | OKRedis.lpush('pn_queue_2', entry.to_json) 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /dashboard/lib/push_test_project.rb: -------------------------------------------------------------------------------- 1 | # API 2 | # --- 3 | # project = PushTestProject.new('com.whatever.foo') 4 | # if !project.construct 5 | # puts "Could not create zip of project. Please contact lou@openkit.io" 6 | # else 7 | # puts "Project is at: #{project.path_to_zip}" 8 | # end 9 | # 10 | require 'mustache' 11 | 12 | class PushTestProject 13 | attr_accessor :path_to_zip 14 | 15 | def initialize(bundle_identifier) 16 | @bundle_identifier = bundle_identifier 17 | end 18 | 19 | def construct 20 | success = false 21 | Dir.mktmpdir do |dir| # automatically removed 22 | begin 23 | FileUtils.cp_r(Rails.root.join('files', 'OKPushTest'), dir) 24 | d1 = Pathname.new(dir).join('OKPushTest') 25 | d2 = d1.join('OKPushTest') 26 | plist_template = d2.join('Info-Template.plist') 27 | plist_output = d2.join('OKPushTest-Info.plist') 28 | plist_template_contents = File.read(plist_template) 29 | 30 | File.open(plist_output, 'w') do |f| 31 | f.print Mustache.render(plist_template_contents, :bundle_id => @bundle_identifier) 32 | end 33 | FileUtils.rm(plist_template) 34 | 35 | self.path_to_zip = "#{Dir.mktmpdir}/OKPushTest.zip" # new dir to persist 36 | success = system("cd #{dir}; zip -r #{path_to_zip} ./") # nice and portable 37 | rescue 38 | end 39 | end 40 | success 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /dashboard/lib/random_gen.rb: -------------------------------------------------------------------------------- 1 | =begin 2 | 3 | Usage: 4 | RandomGen.uppercase_string(5) #=> "AFMFY" 5 | RandomGen.alphanumeric_string(5) #=> "w9t6F" 6 | RandomGen.string(['a','b','c'], 5) #=> "baac" 7 | 8 | =end 9 | module RandomGen 10 | 11 | @@alpha_upper = ('A'..'Z').to_a 12 | @@alpha_lower = ('a'..'z').to_a 13 | @@numeric = ('0'..'9').to_a 14 | @@alphanumeric = @@alpha_upper + @@alpha_lower + @@numeric 15 | 16 | class << self 17 | def uppercase_string(length) 18 | string(@@alpha_upper, length) 19 | end 20 | 21 | def alphanumeric_string(length) 22 | string(@@alphanumeric, length) 23 | end 24 | 25 | def string(choices, length) 26 | s = '' 27 | length.times { s << choices[rand(choices.size)] } 28 | s 29 | end 30 | end 31 | 32 | end 33 | 34 | -------------------------------------------------------------------------------- /dashboard/lib/tasks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/lib/tasks/.gitkeep -------------------------------------------------------------------------------- /dashboard/lib/tasks/setup.rake: -------------------------------------------------------------------------------- 1 | namespace :setup do 2 | 3 | desc "Start mysql server and redis" 4 | task :prereqs do 5 | puts "NOTE: This task assumes you have installed redis and mysql via homebrew.\n\n" 6 | test_running =-> (name, cmd) do 7 | if system "ps -ef | grep #{name} | grep -v grep > /dev/null" 8 | puts "Skipping #{name}, already running." 9 | else 10 | print "Starting #{name} in background..." 11 | if system "#{cmd} 1>/dev/null 2>&1" 12 | puts HighLine.color "succeeded.", :green 13 | else 14 | puts HighLine.color "FAILED!", :red 15 | puts "\tTry running the command:\n\t$ #{cmd}" 16 | end 17 | end 18 | end 19 | 20 | test_running.('mysqld', 'mysql.server start') 21 | test_running.('redis-server', 'redis-server /usr/local/etc/redis.conf --daemonize yes') 22 | end 23 | 24 | 25 | desc "Creates a test app, for use with api_tester.rb" 26 | task :api_test_app => :environment do 27 | Developer.destroy_all(email: 'end_to_end@example.com') 28 | dev = Developer.create!(email: 'end_to_end@example.com', name: 'Test Developer', password: 'password', password_confirmation: 'password') 29 | app = dev.apps.create!(name: 'End to end test') 30 | app.send(:remove_secret_from_redis) 31 | app.update_attribute(:app_key, 'end_to_end_test') 32 | app.update_attribute(:secret_key, 'TL5GGqzfItqZErcibsoYrNAuj7K33KpeWUEAYyyU') 33 | app.send(:store_secret_in_redis) 34 | puts "Created:\n\tkey: #{app.app_key}\n\tsecret: #{app.secret_key}" 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /dashboard/lib/tasks/test.rake: -------------------------------------------------------------------------------- 1 | require "rake/testtask" 2 | 3 | Rake::TestTask.new(:test => 'db:test:prepare') do |t| 4 | t.libs << "test" 5 | t.pattern = "test/**/*_test.rb" 6 | end 7 | 8 | task :default => :test 9 | -------------------------------------------------------------------------------- /dashboard/ok_wildcard.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEgzCCA2ugAwIBAgIJAJSfuiYd97wVMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD 3 | VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5j 4 | aXNjbzEVMBMGA1UEChMMT3BlbktpdCBJbmMuMRUwEwYDVQQDFAwqLm9wZW5raXQu 5 | aW8xHTAbBgkqhkiG9w0BCQEWDmxvdUBvcGVua2l0LmlvMB4XDTEzMTAyNzE3Mzkw 6 | MFoXDTMzMTAyMjE3MzkwMFowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxp 7 | Zm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRUwEwYDVQQKEwxPcGVuS2l0 8 | IEluYy4xFTATBgNVBAMUDCoub3BlbmtpdC5pbzEdMBsGCSqGSIb3DQEJARYObG91 9 | QG9wZW5raXQuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5B0Sa 10 | hjwJIMS6xt1yzs3ZhCUf6UBQRpzhYMhBWKKtwfLUSag/kHMTz9jw/gbn1LYmTipP 11 | Z3aSXc8WqgFC+2L1N5YyKh74Tc35AmiX/zzYpUYVjant5rrvnAjxhYgnyPplKe8J 12 | iOet/+y0VIf4DLgSIrkPq5QtQ14SRgf4lAnlIrtjjjVnaDNCBEz4ZUYZrDsdS3kT 13 | /x3kps9YtyRVqHlDs1JMpEFOtMlb4yv9BsTsh4mvrCNlLr6LGzQrxf5S6hKouddL 14 | djJEzuiPWJxRO/vC4LZ7OaK043U8gDJ8vSJ+nQw+KCXTEpFksiaMCtfKm/ARPZCM 15 | EXU/O/Bnv8JRuHJRAgMBAAGjge8wgewwHQYDVR0OBBYEFLO8ZjVh/U0Gc8mjbipS 16 | yxfxcel6MIG8BgNVHSMEgbQwgbGAFLO8ZjVh/U0Gc8mjbipSyxfxcel6oYGNpIGK 17 | MIGHMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN 18 | U2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMT3BlbktpdCBJbmMuMRUwEwYDVQQDFAwq 19 | Lm9wZW5raXQuaW8xHTAbBgkqhkiG9w0BCQEWDmxvdUBvcGVua2l0LmlvggkAlJ+6 20 | Jh33vBUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAp5m6uuV8wVlf 21 | lpBdwC5ZzfVrZ+TsQlVMwIaAg6uwQheDMeyG0hAoaInueJlcTb5fsD8Pdhml6nWF 22 | lFsqnFiOc0QN9RvjfPsS6NfsY6OYVGcr9trSBfwIXiKQrf3daCcrNEoAn9Wa4jEr 23 | R0fAisf0lc++isev8q243xAeBbYthn3fhP8xeBrYsfzjmFJgOUHbtr3QZ/XBrilA 24 | YYSUWFHOje95+iKGmPw6pCsklVyN9mWySSOG6gZ9CWpV/N/JF943TLBsbsTBPZ4B 25 | PJR44AavMsP6PR3fYObrX/3DxRe90lQ2x/LUGfwEomc1iwxmKTkIKXzZzBY57swM 26 | InZ7ZnUa/g== 27 | -----END CERTIFICATE----- 28 | -------------------------------------------------------------------------------- /dashboard/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /dashboard/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe you tried to change something you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /dashboard/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /dashboard/public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/public/favicon.ico -------------------------------------------------------------------------------- /dashboard/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /dashboard/script/delayed_job: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) 4 | require 'delayed/command' 5 | Delayed::Command.new(ARGV).daemonize 6 | -------------------------------------------------------------------------------- /dashboard/script/immafile.txt: -------------------------------------------------------------------------------- 1 | hello world. 2 | -------------------------------------------------------------------------------- /dashboard/script/push_test.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'push_service.rb')) 2 | 3 | push_service = PushService.new(:dev) 4 | push_service.connect 5 | push_service.write("7263097dd87a783c5d90dfa61ad3df3d17b11428143c788e77c1be4c2d162d38", {aps: {alert: "This is cool!", badge: 1, sound: "default"}, other_meta: 10}) 6 | push_service.disconnect 7 | -------------------------------------------------------------------------------- /dashboard/script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /dashboard/test/factories.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | 3 | factory :developer do 4 | sequence(:email) { |n| "email#{n}@example.com" } 5 | password 'password' 6 | password_confirmation { password } 7 | end 8 | 9 | factory :app do 10 | developer 11 | sequence(:name) { |x| "test_game#{x}" } 12 | end 13 | 14 | factory :leaderboard do 15 | app 16 | sequence(:name) { |n| "leaderboard#{n}" } 17 | trait :high_value do 18 | sort_type 'HighValue' 19 | end 20 | trait :low_value do 21 | sort_type 'LowValue' 22 | end 23 | end 24 | 25 | factory :achievement do 26 | app 27 | sequence(:name) { |n| "achievement#{n}" } 28 | desc "Reach a goal of X and get Y points" 29 | goal 100 30 | points 5 31 | end 32 | 33 | factory :achievement_score do 34 | achievement 35 | user 36 | progress 1 37 | end 38 | 39 | factory :user do 40 | developer 41 | sequence(:nick) { |n| "Fake #{n}" } 42 | sequence(:custom_id) { |n| n.to_s } 43 | end 44 | 45 | factory :subscription do 46 | user 47 | app 48 | end 49 | 50 | factory :score do 51 | leaderboard 52 | user 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /dashboard/test/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/test/integration/.gitkeep -------------------------------------------------------------------------------- /dashboard/test/integration/achievements_api_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class AchievementsApiTest < ActionDispatch::IntegrationTest 4 | 5 | def setup 6 | @game = FactoryGirl.create(:app) 7 | OpenKit::Config.app_key = @game.app_key 8 | OpenKit::Config.secret_key = @game.secret_key 9 | end 10 | 11 | 12 | test "an empty achievement list" do 13 | get '/achievements' 14 | assert response.success? 15 | assert_equal '[]', response.body 16 | end 17 | 18 | 19 | test "achievement list with one achievement" do 20 | achievement = FactoryGirl.create(:achievement, :app => @game) 21 | get '/achievements' 22 | assert response.success? 23 | achievements_json = JSON.parse(response.body) 24 | assert_equal achievement.id, achievements_json[0]['id'] 25 | end 26 | 27 | 28 | test "user progress returned in list of achievements if user_id included in GET" do 29 | achievement = create(:achievement, :app => @game, :goal => 4) 30 | user = create_subscribed_user_for(@game) 31 | 32 | get "/achievements" 33 | a1 = JSON.parse(response.body).first 34 | refute a1.keys.include? 'progress' 35 | 36 | get "/achievements?user_id=#{user.id}" 37 | a2 = JSON.parse(response.body).first 38 | assert a2.keys.include? 'progress' 39 | assert_equal 0, a2['progress'] 40 | 41 | create(:achievement_score, :achievement => achievement, :user => user, :progress => 1) 42 | get "/achievements?user_id=#{user.id}" 43 | a3 = JSON.parse(response.body).first 44 | assert a3.keys.include? 'progress' 45 | assert_equal 1, a3['progress'] 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /dashboard/test/integration/leaderboards_api_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class LeaderboardsApiTest < ActionDispatch::IntegrationTest 4 | 5 | def create_leaderboard_for(app) 6 | app.leaderboards.create!(:name => 'foo', :sort_type => 'HighValue') 7 | end 8 | 9 | def setup 10 | @game = FactoryGirl.create(:app) 11 | OpenKit::Config.app_key = @game.app_key 12 | OpenKit::Config.secret_key = @game.secret_key 13 | end 14 | 15 | 16 | def test_empty_array 17 | get '/leaderboards' 18 | assert response.success? 19 | assert_equal '[]', response.body 20 | assert_blank JSON.parse(response.body) 21 | end 22 | 23 | 24 | def test_single_leaderboard 25 | leaderboard = create_leaderboard_for(@game) 26 | get '/leaderboards' 27 | assert response.success? 28 | assert_equal 1, JSON.parse(response.body).count 29 | end 30 | 31 | 32 | def test_versioned_leaderboards 33 | leaderboard = create_leaderboard_for(@game) 34 | leaderboard.tag_list << 'v2' 35 | leaderboard.save 36 | 37 | get '/leaderboards?tag=v1' 38 | assert_equal 0, JSON.parse(response.body).count 39 | 40 | get '/leaderboards?tag=v2' 41 | list = JSON.parse(response.body) 42 | assert_equal 1, list.count 43 | assert_equal leaderboard.id, list[0]['id'] 44 | end 45 | 46 | 47 | def test_show 48 | leaderboard = create_leaderboard_for(@game) 49 | get "/leaderboards/#{leaderboard.id}" 50 | leaderboard_json = JSON.parse(response.body) 51 | assert_equal leaderboard.id, leaderboard_json['id'] 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /dashboard/test/integration/users_api_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UsersApiTest < ActionDispatch::IntegrationTest 4 | 5 | def setup 6 | @game = FactoryGirl.create(:app) 7 | @leaderboard = FactoryGirl.create(:leaderboard, :low_value, :app => @game) 8 | OpenKit::Config.app_key = @game.app_key 9 | OpenKit::Config.secret_key = @game.secret_key 10 | end 11 | 12 | def test_user_create 13 | post '/users', {user: {nick: "Lou Zell", custom_id: "123"}} 14 | assert response.success? 15 | u = JSON.parse(response.body) 16 | assert_kind_of Integer, u['id'] 17 | assert_equal "123", u['custom_id'] 18 | assert_equal "Lou Zell", u['nick'] 19 | # TODO: make this belong_to :app instead 20 | assert_equal @game.developer_id, u['developer_id'] 21 | end 22 | 23 | 24 | def test_user_subscribe 25 | post '/users', {user: {nick: "Lou Zell", custom_id: "123"}} 26 | u1 = JSON.parse(response.body) 27 | assert_not_nil u1['id'] 28 | 29 | # Create a second app by this developer 30 | @game2 = FactoryGirl.create(:app, :developer => @game.developer) 31 | OpenKit::Config.app_key = @game2.app_key 32 | OpenKit::Config.secret_key = @game2.secret_key 33 | post '/users', {user: {nick: "Lou Zell", custom_id: "123"}} 34 | u2 = JSON.parse(response.body) 35 | assert_equal u1['id'], u2['id'] # Same user row! 36 | 37 | # Create a third app by a _new_ developer 38 | @game3 = FactoryGirl.create(:app) 39 | OpenKit::Config.app_key = @game3.app_key 40 | OpenKit::Config.secret_key = @game3.secret_key 41 | post '/users', {user: {nick: "Lou Zell", custom_id: "123"}} 42 | u3 = JSON.parse(response.body) 43 | assert_not_equal u3['id'], u1['id'] # Important! New user row created! 44 | end 45 | 46 | 47 | def test_user_update 48 | post '/users', {user: {nick: "Lou Zell", custom_id: "123"}} 49 | u1 = JSON.parse(response.body) 50 | put "/users/#{u1['id']}", {nick: "Lou Z"} 51 | u2 = JSON.parse(response.body) 52 | assert_equal u1['id'], u2['id'] 53 | assert_equal "Lou Z", u2['nick'] 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /dashboard/test/middleware/request_signature_test_helper.rb: -------------------------------------------------------------------------------- 1 | module RequestSignatureTestHelper 2 | 3 | def self.included(base) 4 | OpenKit::Config.skip_https = true # to match rack-test 5 | OpenKit::Config.host = "example.org" # to match rack-test 6 | end 7 | 8 | 9 | # This creates a new GET request using the openkit gem, but it doesn't 10 | # perform the request. We are using it to get the authorization header 11 | # that we need for a succesful request through the two_legged_oauth middleware. 12 | def rack_auth_for_get(path) 13 | uri = URI(path) 14 | query_params = uri.query && Rack::Utils.parse_query(uri.query) || {} 15 | r = OpenKit::Request::Get.new(path, query_params) 16 | rack_auth_header(r.net_request) 17 | end 18 | 19 | def rack_auth_for_post(path, params) 20 | r = OpenKit::Request::Post.new(path, params) 21 | rack_auth_header(r.net_request) 22 | end 23 | 24 | def rack_auth_for_put(path, params) 25 | r = OpenKit::Request::Put.new(path, params) 26 | rack_auth_header(r.net_request) 27 | end 28 | 29 | def rack_auth_for_multi(path, params, filepath, file_param) 30 | upload = OpenKit::Request::Upload.new(file_param, filepath) 31 | r = OpenKit::Request::PostMultipart.new(path, params, upload) 32 | rack_auth_header(r.net_request) 33 | end 34 | 35 | private 36 | def rack_auth_header(net_http_request) 37 | {'HTTP_AUTHORIZATION' => net_http_request['AUTHORIZATION']} 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /dashboard/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] = "test" 2 | require File.expand_path("../../config/environment", __FILE__) 3 | require File.expand_path("../middleware/request_signature_test_helper", __FILE__) 4 | require "rails/test_help" 5 | require 'mocha/setup' 6 | require 'authlogic/test_case' 7 | include Authlogic::TestCase 8 | 9 | FactoryGirl.find_definitions 10 | 11 | class ActiveSupport::TestCase 12 | self.use_transactional_fixtures = true 13 | include FactoryGirl::Syntax::Methods 14 | end 15 | 16 | class ActionDispatch::IntegrationTest 17 | include RequestSignatureTestHelper 18 | 19 | def get_with_signature(path) 20 | self.host = "example.org" 21 | get_without_signature(path, {}, rack_auth_for_get(path)) 22 | end 23 | 24 | def post_with_signature(path, req_params) 25 | self.host = "example.org" 26 | headers = rack_auth_for_post(path, req_params) 27 | headers.merge!({'CONTENT_TYPE' => 'application/json'}) 28 | post_without_signature(path, req_params.to_json, headers) 29 | end 30 | 31 | def put_with_signature(path, req_params) 32 | self.host = "example.org" 33 | headers = rack_auth_for_put(path, req_params) 34 | headers.merge!({'CONTENT_TYPE' => 'application/json'}) 35 | put_without_signature(path, req_params.to_json, headers) 36 | end 37 | 38 | alias_method_chain :get, :signature 39 | alias_method_chain :post, :signature 40 | alias_method_chain :put, :signature 41 | 42 | def create_subscribed_user_for(app) 43 | user = create(:user, :developer => app.developer) 44 | create(:subscription, :user => user, :app => app) 45 | user 46 | end 47 | 48 | def random_alphanumeric(n) 49 | Array.new(n){[*'0'..'9', *'a'..'z', *'A'..'Z'].sample}.join 50 | end 51 | end 52 | 53 | Turn.config do |c| 54 | c.format = :outline # :progress 55 | end 56 | -------------------------------------------------------------------------------- /dashboard/test/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/test/unit/.gitkeep -------------------------------------------------------------------------------- /dashboard/test/unit/change_password_test.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper')) 2 | 3 | class ChangePasswordTest < ActiveSupport::TestCase 4 | setup :activate_authlogic 5 | 6 | def setup 7 | @dev = Developer.new(:email => "foo@example.com", :password => "oldpassword", :password_confirmation => "oldpassword") 8 | @dev.save! 9 | @model = ChangePassword.new(current_password: "oldpassword", 10 | new_password: "newpassword", 11 | new_password_confirmation: "newpassword", 12 | developer: @dev) 13 | @model.save 14 | end 15 | 16 | test "that we were able to update the password" do 17 | assert @model.errors.empty? 18 | end 19 | 20 | test "that we cannot login with the old password" do 21 | session = DeveloperSession.new(:email => @dev.email, :password => "oldpassword") 22 | assert !session.valid?, "Old password still works!" 23 | end 24 | 25 | test "that we can login with new password" do 26 | session = DeveloperSession.new(:email => @dev.email, :password => "newpassword") 27 | assert session.valid? 28 | end 29 | 30 | # We're testing whether ChangePassword follows the ActiveRecord API by 31 | # setting up a @model and including the ActiveModel::Lint::Tests 32 | include ActiveModel::Lint::Tests 33 | end 34 | -------------------------------------------------------------------------------- /dashboard/test/unit/helpers/scores_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ScoresHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /dashboard/test/unit/helpers/users_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UsersHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /dashboard/test/unit/user_test.rb: -------------------------------------------------------------------------------- 1 | # To run only this test: 2 | # $ ruby -Itest test/unit/user_test.rb 3 | require 'test_helper' 4 | 5 | class UserTest < ActiveSupport::TestCase 6 | 7 | def setup 8 | dev = Developer.create!( 9 | :email => 'lzell11@gmail.com', 10 | :name => 'Lou Zell', 11 | :password => 'password', 12 | :password_confirmation => 'password') 13 | 14 | app = dev.apps.new(:name => 'My App!') 15 | app.save 16 | 17 | @app_key = app.app_key 18 | end 19 | 20 | 21 | test "can create via custom_id" do 22 | assert_equal 0, User.count 23 | 24 | authorized_app = App.find_by(app_key: @app_key) 25 | user_params = { 26 | :nick => 'Foo', 27 | :custom_id => '123' 28 | } 29 | 30 | @user = authorized_app.find_or_create_subscribed_user(user_params) 31 | assert_equal 1, User.count 32 | assert_equal '123', User.first.custom_id 33 | end 34 | 35 | test "should require custom_id, twitter_id, fb_id, or google_id" do 36 | authorized_app = App.find_by(app_key: @app_key) 37 | 38 | user = authorized_app.find_or_create_subscribed_user({:nick => 'Foo'}) 39 | assert user.new_record? 40 | 41 | %w(fb_id twitter_id google_id custom_id).each do |service_id| 42 | user = authorized_app.find_or_create_subscribed_user({:nick => 'Foo', service_id => 9}) 43 | assert !user.new_record? 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /dashboard/vendor/assets/javascripts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/vendor/assets/javascripts/.gitkeep -------------------------------------------------------------------------------- /dashboard/vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/vendor/assets/stylesheets/.gitkeep -------------------------------------------------------------------------------- /dashboard/vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKit/openkit-server/ba5ff7d59da7461d188c165b400c1c6415d3318f/dashboard/vendor/plugins/.gitkeep -------------------------------------------------------------------------------- /dashboard/zeus.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "ruby -rubygems -r./custom_plan -eZeus.go", 3 | 4 | "plan": { 5 | "boot": { 6 | "default_bundle": { 7 | "development_environment": { 8 | "prerake": {"rake": []}, 9 | "runner": ["r"], 10 | "console": ["c"], 11 | "server": ["s"], 12 | "generate": ["g"], 13 | "destroy": ["d"], 14 | "dbconsole": [] 15 | }, 16 | "test_environment": { 17 | "test_helper": { 18 | "test": ["t"] 19 | } 20 | } 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /provisioning/Gemfile: -------------------------------------------------------------------------------- 1 | gem 'colorize' 2 | -------------------------------------------------------------------------------- /provisioning/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | colorize (0.6.0) 4 | 5 | PLATFORMS 6 | ruby 7 | 8 | DEPENDENCIES 9 | colorize 10 | -------------------------------------------------------------------------------- /provisioning/README.md: -------------------------------------------------------------------------------- 1 | Server Provisioning 2 | ------------------- 3 | 4 | This is the start of a readme that will have you up and running on your 5 | OpenKit system. WIP. 6 | 7 | Dependencies: 8 | 9 | $ brew install python 10 | $ pip install awscli 11 | $ aws configure 12 | 13 | 14 | One time configuration: 15 | 16 | $ bin/create_security_groups 17 | 18 | Boot an instance: 19 | 20 | $ bundle install 21 | $ rake 22 | $ bin/boot_instance small -a HTTP 23 | -------------------------------------------------------------------------------- /provisioning/Rakefile: -------------------------------------------------------------------------------- 1 | setup_deps = [ 2 | :system_dependency_check, 3 | :write_bootstrap_file 4 | ] 5 | 6 | task :setup => setup_deps do 7 | puts "You are now ready to launch instances with bin/boot_instance" 8 | end 9 | 10 | task :system_dependency_check do 11 | require_relative 'lib/dependency_check' 12 | DependencyCheck.new.run 13 | end 14 | 15 | task :write_bootstrap_file do 16 | require_relative 'lib/bootstrap_file_writer' 17 | BootstrapFileWriter.new.run 18 | end 19 | 20 | task :default => ['setup'] 21 | -------------------------------------------------------------------------------- /provisioning/bin/create_security_groups: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Dependencies: 4 | # * http://aws.amazon.com/cli 5 | # 6 | 7 | aws ec2 create-security-group --group-name OK_NETWORK --description "Apply to all instances" 8 | aws ec2 authorize-security-group-ingress --source-group OK_NETWORK --group-name OK_NETWORK --protocol tcp --port 22 9 | aws ec2 authorize-security-group-ingress --source-group OK_NETWORK --group-name OK_NETWORK --protocol tcp --port 3306 10 | aws ec2 authorize-security-group-ingress --source-group OK_NETWORK --group-name OK_NETWORK --protocol tcp --port 6379 11 | aws ec2 authorize-security-group-ingress --source-group OK_NETWORK --group-name OK_NETWORK --protocol tcp --port 80 12 | aws ec2 authorize-security-group-ingress --source-group OK_NETWORK --group-name OK_NETWORK --protocol tcp --port 443 13 | 14 | aws ec2 create-security-group --group-name SSH --description "public ssh" 15 | aws ec2 authorize-security-group-ingress --group-name SSH --protocol tcp --cidr 0.0.0.0/0 --port 22 16 | aws ec2 create-security-group --group-name HTTP --description "public http" 17 | aws ec2 authorize-security-group-ingress --group-name HTTP --protocol tcp --cidr 0.0.0.0/0 --port 80 18 | aws ec2 create-security-group --group-name HTTPS --description "public https" 19 | aws ec2 authorize-security-group-ingress --group-name HTTPS --protocol tcp --cidr 0.0.0.0/0 --port 443 20 | -------------------------------------------------------------------------------- /provisioning/lib/bootstrap_file_writer.rb: -------------------------------------------------------------------------------- 1 | require 'erb' 2 | require_relative 'system_config' 3 | 4 | class BootstrapFileWriter 5 | 6 | def initialize 7 | @email = SystemConfig['email'] 8 | @public_key = SystemConfig['public_key'] 9 | raise "Email missing from system config" unless @email 10 | raise "Public key missing from system config" unless @public_key 11 | end 12 | 13 | def run 14 | output_file = File.join provisioning_root, "tmp", "bootstrap_min.userdata" 15 | begin 16 | File.open output_file, "w" do |f| 17 | f.print rendered_template 18 | end 19 | rescue => e 20 | STDERR.puts "Could not write boostrap file, error:\n\n" 21 | raise e 22 | end 23 | end 24 | 25 | def rendered_template 26 | template = File.join provisioning_root, "templates", "bootstrap_min.userdata.erb" 27 | erb = ERB.new File.read(template) 28 | erb.result(binding) 29 | end 30 | 31 | def provisioning_root 32 | File.expand_path "../..", __FILE__ 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /provisioning/lib/dependency_check.rb: -------------------------------------------------------------------------------- 1 | require 'colorize' 2 | require_relative 'system_config' 3 | 4 | class DependencyCheck 5 | 6 | def list 7 | [:aws_cli, :openkit_config] 8 | end 9 | 10 | def run 11 | list.each do |x| 12 | check_system_for(x) 13 | end 14 | end 15 | 16 | def check_system_for(x) 17 | print "checking system for #{x}..." 18 | if has(x) 19 | puts "found".green 20 | else 21 | puts "not found".red 22 | error_on(x) 23 | exit 1 24 | end 25 | end 26 | 27 | # system checks and error messages go here 28 | def has_aws_cli 29 | system("which aws 2>&1 1>/dev/null") && 30 | `aws --version 2>&1` =~ /aws-cli/ 31 | end 32 | 33 | def error_on_aws_cli 34 | STDERR.print <<-EOS 35 | 36 | Amazon's command line tool is required for the provisioning scripts. 37 | Install it with: 38 | $ brew install python 39 | $ pip install awscli 40 | $ aws configure 41 | EOS 42 | end 43 | 44 | def has_openkit_config 45 | system "test -e #{SystemConfig.path}" 46 | end 47 | 48 | def error_on_openkit_config 49 | STDERR.print <<-EOS 50 | 51 | An OpenKit system configuration file is required at the top level 52 | of the openkit-server project. An example file is provided at 53 | openkit-server/#{SystemConfig.example_name}. You should move it into place 54 | with: 55 | 56 | $ mv #{SystemConfig.example_name} #{SystemConfig.name} 57 | 58 | Then edit the file to contain real values. 59 | EOS 60 | end 61 | 62 | 63 | private 64 | def has(name) 65 | method("has_#{name}").call 66 | end 67 | 68 | def error_on(name) 69 | method("error_on_#{name}").call 70 | end 71 | end 72 | 73 | -------------------------------------------------------------------------------- /provisioning/lib/system_config.rb: -------------------------------------------------------------------------------- 1 | require 'yaml' 2 | 3 | module SystemConfig 4 | extend self 5 | 6 | def yaml 7 | @yaml ||= YAML.load_file(path) 8 | end 9 | 10 | def [](k) 11 | yaml[k] 12 | end 13 | 14 | def example_name 15 | "#{name}.example" 16 | end 17 | 18 | def name 19 | "system.yml" 20 | end 21 | 22 | def path 23 | "#{project_root}/#{name}" 24 | end 25 | 26 | def current_dir 27 | File.expand_path "..", __FILE__ 28 | end 29 | 30 | def project_root 31 | File.join current_dir, "../.." 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /provisioning/templates/bootstrap_min.userdata.erb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "<%= @public_key %>" >> /home/ec2-user/.ssh/authorized_keys 4 | yum update -y 5 | 6 | # Prepare for ssh forward agent across sudo 7 | # echo 'Defaults env_keep += SSH_AUTH_SOCK' >> /etc/sudoers 8 | 9 | # Notify <%= @email %> that we're done. 10 | PUBLIC_HOSTNAME=$(curl -s http://169.254.169.254/latest/meta-data/public-hostname) 11 | sendmail -t < 13 | subject:Server Bootstrapped 14 | Instance is up. Access with: 15 | ssh ec2-user@$PUBLIC_HOSTNAME 16 | EOM 17 | -------------------------------------------------------------------------------- /system.yml.example: -------------------------------------------------------------------------------- 1 | email: "lou@example.org" 2 | public_key: "ssh-rsa AAAAFAKEFAKEFAKEAAADAQABAAABAQDFRzB64kvrxWHOE8zRYqb9K1hCqFWViw5I2PZyWXAm675ETZGXV+37H+RRUtIlNDecNF41G4qRBqo34IxORgppVuuFPNibc576u6nCFJbNRjiTV8BonhYTKgpFCl+4HfvxD/TLdbOSf1CkgDn0wkEXKF+ASxv+By6DC05jRxtAUv0dIA/LBrHThbCPremzfXhsw+3qJUDCdFfmMiWcEs4In7SPuPEnTT5WTx1QJNmFyrGktyuPzim1iWN53IpapXsMqvE0ZDGVsECoYV8OvRQXesAV5l+hp2rbH00ZI8HVCmp9WTq2bUA8cE49miFa0kS0WDlyPtO5COcROsk+Jngf lou@mac.local" 3 | --------------------------------------------------------------------------------