mirror of
http://ghproxy.cn/https://github.com/multunus/onemdm-server
synced 2025-12-06 02:04:57 +00:00
Add GCM push for pushing OneMDM app to devices
This commit is contained in:
@@ -3,31 +3,41 @@ ActiveAdmin.register_page "Dashboard" do
|
||||
menu priority: 1, label: proc{ I18n.t("active_admin.dashboard") }
|
||||
|
||||
content title: proc{ I18n.t("active_admin.dashboard") } do
|
||||
div class: "blank_slate_container", id: "dashboard_default_message" do
|
||||
span class: "blank_slate" do
|
||||
span I18n.t("active_admin.dashboard_welcome.welcome")
|
||||
small I18n.t("active_admin.dashboard_welcome.call_to_action")
|
||||
|
||||
panel "Recent Pushes" do
|
||||
table_for BatchInstallation.order('id desc').limit(10) do
|
||||
column "Pushed on" do |batch|
|
||||
batch.created_at
|
||||
end
|
||||
column "App Name" do |batch|
|
||||
batch.app.name
|
||||
end
|
||||
column "# Devices" do |batch|
|
||||
link_to batch.installations.count,
|
||||
admin_devices_path(q: {installations_batch_installation_id_eq: batch.id})
|
||||
end
|
||||
column "# Installed" do |batch|
|
||||
link_to batch.installations.installed.count,
|
||||
admin_devices_path(q: {installations_batch_installation_id_eq: batch.id,
|
||||
installations_status_eq: Installation.statuses[:installed]})
|
||||
end
|
||||
column "# Cancelled" do |batch|
|
||||
link_to batch.installations.cancelled.count,
|
||||
admin_devices_path(q: {installations_batch_installation_id_eq: batch.id,
|
||||
installations_status_eq: Installation.statuses[:cancelled]})
|
||||
end
|
||||
column "# Pending" do |batch|
|
||||
link_to batch.installations.pushed.count + batch.installations.downloaded.count,
|
||||
admin_devices_path(q: {installations_batch_installation_id_eq: batch.id,
|
||||
installations_status_in: [Installation.statuses[:pushed],
|
||||
Installation.statuses[:downloaded]]})
|
||||
end
|
||||
column "% Success" do |batch|
|
||||
total = batch.installations.count
|
||||
installed = batch.installations.installed.count
|
||||
percentage_success = (installed/total) * 100 if total > 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Here is an example of a simple dashboard with columns and panels.
|
||||
#
|
||||
# columns do
|
||||
# column do
|
||||
# panel "Recent Posts" do
|
||||
# ul do
|
||||
# Post.recent(5).map do |post|
|
||||
# li link_to(post.title, admin_post_path(post))
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
||||
# column do
|
||||
# panel "Info" do
|
||||
# para "Welcome to ActiveAdmin."
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
end # content
|
||||
end
|
||||
|
||||
@@ -2,18 +2,21 @@ ActiveAdmin.register Device do
|
||||
|
||||
actions :all, except: [:edit,:new]
|
||||
|
||||
# See permitted parameters documentation:
|
||||
# https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters
|
||||
#
|
||||
# permit_params :list, :of, :attributes, :on, :model
|
||||
#
|
||||
# or
|
||||
#
|
||||
# permit_params do
|
||||
# permitted = [:permitted, :attributes]
|
||||
# permitted << :other if resource.something?
|
||||
# permitted
|
||||
# end
|
||||
app_data = lambda do
|
||||
apps = App.order('name').reload.pluck(:name,:id)
|
||||
{"App Name" => apps}
|
||||
end
|
||||
|
||||
batch_action :push, confirm: "Select apps to push",form: app_data do |ids,inputs|
|
||||
app = App.find(inputs["App Name"])
|
||||
batch = BatchInstallation.create(:app => app)
|
||||
ids.each do | id |
|
||||
install = Installation.new(device: Device.find(id),batch_installation: batch)
|
||||
install.pushed!
|
||||
end
|
||||
redirect_to admin_dashboard_path, notice: "Successfully pushed app to device(s)"
|
||||
end
|
||||
|
||||
index do
|
||||
selectable_column
|
||||
id_column
|
||||
|
||||
@@ -17,4 +17,8 @@ class ApplicationController < ActionController::Base
|
||||
def render_unauthorized
|
||||
render json: "Bad token", status: :unauthorised
|
||||
end
|
||||
|
||||
def set_timezone_for_admin
|
||||
Time.zone = "Mumbai"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
class App < ActiveRecord::Base
|
||||
|
||||
has_many :batch_installations, dependent: :destroy
|
||||
|
||||
validates :name, :package_name, presence: true
|
||||
|
||||
def apk_url
|
||||
return DEFAULT_APP_URL if self.package_name.eql?(DEFAULT_APP_PACKAGE_NAME)
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
class BatchInstallation < ActiveRecord::Base
|
||||
belongs_to :app
|
||||
|
||||
has_many :installations, dependent: :destroy
|
||||
end
|
||||
|
||||
@@ -10,6 +10,7 @@ class Device < ActiveRecord::Base
|
||||
after_create :update_last_heartbeats_time
|
||||
|
||||
has_many :heartbeats, dependent: :destroy
|
||||
has_many :installations, dependent: :destroy
|
||||
|
||||
scope :active, -> {where("last_heartbeat_recd_time > '#{Time.now.utc - ACTIVE_TIMEFRAME}'")}
|
||||
scope :missing, -> {where("last_heartbeat_recd_time < '#{Time.now.utc - ACTIVE_TIMEFRAME}'AND last_heartbeat_recd_time > '#{Time.now.utc - MISSING_TIMEFRAME}'")}
|
||||
|
||||
@@ -1,9 +1,28 @@
|
||||
class Installation < ActiveRecord::Base
|
||||
enum status: [:pushed, :downloaded, :cancelled, :installed]
|
||||
|
||||
|
||||
delegate :app, to: :batch_installation
|
||||
|
||||
belongs_to :device
|
||||
belongs_to :batch_installation
|
||||
|
||||
after_create :push_apps
|
||||
|
||||
def as_json(options={})
|
||||
{
|
||||
:id => self.id,
|
||||
:name => self.app.name,
|
||||
:package_name => self.app.package_name,
|
||||
:apk_url => self.app.apk_url
|
||||
}
|
||||
end
|
||||
|
||||
def push_apps
|
||||
if self.pushed?
|
||||
gcm = GCM.new(GCM_KEY)
|
||||
registration_ids = [self.device.gcm_token]
|
||||
options = { data: {message: self.to_json }}
|
||||
response = gcm.send(registration_ids, options)
|
||||
logger.debug "response #{response}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,3 +37,5 @@ module OnemdmServer
|
||||
end
|
||||
STATUS_CLASSES = {active: :ok,missing: :warning,dead: :error}
|
||||
GCM_KEY = "AIzaSyCZ3lVhV2CbIcZ22f1YI_MvPx3C7sMm_2g"
|
||||
DEFAULT_APP_PACKAGE_NAME = "com.multunus.onemdm"
|
||||
DEFAULT_APP_URL = "https://s3.amazonaws.com/onemdm/onemdm.apk"
|
||||
|
||||
@@ -42,5 +42,5 @@ Rails.application.configure do
|
||||
|
||||
ACTIVE_TIMEFRAME = 1.hours
|
||||
MISSING_TIMEFRAME = 2.hours
|
||||
|
||||
#DEFAULT_APP_URL = "http://192.168.2.92:3000/onemdm.apk"
|
||||
end
|
||||
|
||||
@@ -119,7 +119,7 @@ ActiveAdmin.setup do |config|
|
||||
# This allows your users to comment on any resource registered with Active Admin.
|
||||
#
|
||||
# You can completely disable comments:
|
||||
# config.comments = false
|
||||
config.comments = false
|
||||
#
|
||||
# You can disable the menu item for the comments index page:
|
||||
# config.show_comments_in_menu = false
|
||||
@@ -259,6 +259,7 @@ ActiveAdmin.setup do |config|
|
||||
# You can enable or disable them for all resources here.
|
||||
#
|
||||
# config.filters = true
|
||||
config.current_filters = false
|
||||
#
|
||||
# By default the filters include associations in a select, which means
|
||||
# that every record will be loaded for each association.
|
||||
@@ -266,4 +267,6 @@ ActiveAdmin.setup do |config|
|
||||
# of those filters by default here.
|
||||
#
|
||||
# config.include_default_association_filters = true
|
||||
|
||||
config.before_filter :set_timezone_for_admin
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ Rollbar.configure do |config|
|
||||
config.access_token = ENV['ROLLBAR_ACCESS_TOKEN']
|
||||
|
||||
# Here we'll disable in 'test':
|
||||
if Rails.env.test?
|
||||
if Rails.env.test? || Rails.env.development?
|
||||
config.enabled = false
|
||||
end
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Rails.application.routes.draw do
|
||||
# See how all your routes lay out with "rake routes".
|
||||
|
||||
# You can have the root of your site routed with "root"
|
||||
# root 'welcome#index'
|
||||
root 'admin/dashboard#index'
|
||||
|
||||
# Example of regular route:
|
||||
# get 'products/:id' => 'catalog#view'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class CreateApplications < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :applications do |t|
|
||||
create_table :apps do |t|
|
||||
t.string :name
|
||||
t.string :package_name
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
class RenameApplicationToApp < ActiveRecord::Migration
|
||||
def change
|
||||
rename_table :applications, :apps
|
||||
end
|
||||
end
|
||||
@@ -1,8 +1,7 @@
|
||||
class CreateBatchInstallations < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :batch_installations do |t|
|
||||
t.integer :app_id
|
||||
|
||||
t.belongs_to :app, foreign_key: true, index: true
|
||||
t.timestamps null: false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
class CreateInstallations < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :installations do |t|
|
||||
t.integer :device_id
|
||||
t.integer :batch_installation_id
|
||||
t.integer :status
|
||||
t.belongs_to :device, foreign_key: true, index: true
|
||||
t.belongs_to :batch_installation, foreign_key: true, index: true
|
||||
t.integer :status, default: 0, null: false
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
|
||||
10
db/schema.rb
10
db/schema.rb
@@ -62,6 +62,8 @@ ActiveRecord::Schema.define(version: 20151113140645) do
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
add_index "batch_installations", ["app_id"], name: "index_batch_installations_on_app_id", using: :btree
|
||||
|
||||
create_table "devices", force: :cascade do |t|
|
||||
t.string "model"
|
||||
t.string "unique_id"
|
||||
@@ -85,10 +87,16 @@ ActiveRecord::Schema.define(version: 20151113140645) do
|
||||
create_table "installations", force: :cascade do |t|
|
||||
t.integer "device_id"
|
||||
t.integer "batch_installation_id"
|
||||
t.integer "status"
|
||||
t.integer "status", default: 0, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
add_index "installations", ["batch_installation_id"], name: "index_installations_on_batch_installation_id", using: :btree
|
||||
add_index "installations", ["device_id"], name: "index_installations_on_device_id", using: :btree
|
||||
|
||||
add_foreign_key "batch_installations", "apps"
|
||||
add_foreign_key "heartbeats", "devices"
|
||||
add_foreign_key "installations", "batch_installations"
|
||||
add_foreign_key "installations", "devices"
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FactoryGirl.define do
|
||||
factory :app do
|
||||
name "My Ultimate Application"
|
||||
package_name "my.ultimate.application"
|
||||
name "One MDM"
|
||||
package_name "com.multunus.onemdm"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
FactoryGirl.define do
|
||||
factory :batch_installation do
|
||||
app_id 1
|
||||
association :app
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
FactoryGirl.define do
|
||||
factory :installation do
|
||||
device_id 1
|
||||
batch_installation_id 1
|
||||
status 1
|
||||
association :device
|
||||
association :batch_installation
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe App, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
|
||||
let!(:app) { create(:app) }
|
||||
|
||||
it { should validate_presence_of :name }
|
||||
it { should validate_presence_of :package_name }
|
||||
|
||||
end
|
||||
@@ -4,11 +4,12 @@ RSpec.describe Installation, type: :model do
|
||||
it { should belong_to(:device) }
|
||||
it { should belong_to(:batch_installation) }
|
||||
|
||||
|
||||
|
||||
# Create Installation Model [Device ID, batch installation ID, status(Pushed, Downloaded, Cancelled, Installed)]
|
||||
describe "Installation status" do
|
||||
let!(:installation){FactoryGirl.create(:installation)}
|
||||
it "Default status" do
|
||||
expect(installation.status).to eql Installation.statuses.keys[0]
|
||||
end
|
||||
it "Pushed" do
|
||||
installation.pushed!
|
||||
expect(installation.status).to eql Installation.statuses.keys[0]
|
||||
@@ -29,4 +30,17 @@ RSpec.describe Installation, type: :model do
|
||||
|
||||
end
|
||||
|
||||
describe "GCM Push " do
|
||||
let(:installation){FactoryGirl.build(:installation)}
|
||||
|
||||
it "if status is pushed" do
|
||||
expect_any_instance_of(GCM).to receive(:send).and_return(installation)
|
||||
installation.save
|
||||
end
|
||||
it "status is not pushed" do
|
||||
expect_any_instance_of(GCM).not_to receive(:send)
|
||||
installation.cancelled!
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user