Skip to content

Commit

Permalink
Merge pull request #1228 from tryzealot/refactor/register-udid-device
Browse files Browse the repository at this point in the history
重构注册 UDID 设备及相关展示的逻辑
  • Loading branch information
icyleaf authored Aug 4, 2023
2 parents 51efb8d + e06e6a2 commit 84e9ae8
Show file tree
Hide file tree
Showing 23 changed files with 199 additions and 136 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ gem 'active_model_serializers', '~> 0.10.13'
gem 'graphql', '~> 2.0.24'
gem 'rack-cors', '~> 2.0.1'
gem 'health_check', '~> 3.1.0'
gem 'tiny_appstore_connect', '~> 0.1.8'
gem 'tiny_appstore_connect', '~> 0.1.12'

# View
## 模板引擎
Expand Down
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ GEM
responders (3.1.0)
actionpack (>= 5.2)
railties (>= 5.2)
rexml (3.2.5)
rexml (3.2.6)
rouge (4.1.2)
rqrcode (2.2.0)
chunky_png (~> 1.0)
Expand Down Expand Up @@ -500,7 +500,7 @@ GEM
thor (1.2.2)
tilt (2.1.0)
timeout (0.4.0)
tiny_appstore_connect (0.1.8)
tiny_appstore_connect (0.1.12)
CFPropertyList (>= 2.3.4, < 3.1.0)
faraday (>= 1.10.0, < 3.0)
jwt (>= 1.4, < 3)
Expand Down Expand Up @@ -606,7 +606,7 @@ DEPENDENCIES
slim-rails (~> 3.6.2)
stimulus-rails (~> 1.2.1)
sys-filesystem (~> 1.4.3)
tiny_appstore_connect (~> 0.1.8)
tiny_appstore_connect (~> 0.1.12)
turbo-rails (~> 1.4)
vmstat (~> 2.3.0)
web-console (>= 3.3.0)
Expand Down
57 changes: 57 additions & 0 deletions app/controllers/concerns/device_attributes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

module DeviceAttributes
extend ActiveSupport::Concern

def certificate
@certificate ||= lambda do
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = Random.rand(2**16 - 2) + 1
cert.subject = subject
cert.issuer = issuer
cert.not_before = create_date
cert.not_after = expire_date
cert.public_key = root_key.public_key

cert_ext = OpenSSL::X509::ExtensionFactory.new
cert_ext.subject_certificate = cert
cert_ext.issuer_certificate = cert
cert.add_extension(cert_ext.create_extension("basicConstraints","CA:TRUE",true))
cert.add_extension(cert_ext.create_extension("keyUsage","keyCertSign, cRLSign", true))
cert.add_extension(cert_ext.create_extension("subjectKeyIdentifier","hash",false))
cert.add_extension(cert_ext.create_extension("authorityKeyIdentifier","keyid:always",false))
cert.sign(root_key, digest)
cert
end.call
end

def subject
@subject ||= OpenSSL::X509::Name.parse("/C=CN/O=tryzealot/OU=zealot/CN=#{Setting.site_title} Self-signed Authority")
end

def issuer
@issuer ||= OpenSSL::X509::Name.parse("/C=CN/O=tryzealot/OU=zealot/CN=#{Setting.site_title}")
end

def root_key
@key ||= OpenSSL::PKey::RSA.generate(2048)
end

def digest
@digest ||= OpenSSL::Digest.new('SHA256')
end

def payload_uuid
@payload_uuid ||= Rails.cache.fetch('ios-udid', expires_in: 1.week) { SecureRandom.uuid.upcase }
end

def create_date
Time.now.utc
end

def expire_date
expire_time = 1 * 365 * 24 * 60 * 60 # 1 year
create_date + expire_time
end
end
93 changes: 23 additions & 70 deletions app/controllers/udid_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

class UdidController < ApplicationController
include DeviceAttributes
include Qrcode

before_action :set_device_xml, only: :create
Expand Down Expand Up @@ -46,13 +47,16 @@ def update

# POST /udid/:udid/register
def register
apple_key = AppleKey.find(params[:apple_key_id])
apple_key = AppleKey.find(device_params[:apple_keys])
name = device_params[:name]
name = [ 'Zealot', params[:product], SecureRandom.hex(4) ].compact.join('-') if name.blank? # Max 50 chars
udid = params[:udid]
name = [ 'Zealot', params[:product], SecureRandom.hex(4) ].compact.join('-') # Max 50 chars

new_device = apple_key.register_device(udid, name)
if new_device.errors
flash[:alter] = new_device.errors.messages[:devices][0]
unless new_device.valid?
logger.debug "Register failed with errors: #{new_device.errors}"
error_message = new_device.errors.messages[:devices][0]
flash[:alter] = error_message if error_message.present?
return render :show, status: :unprocessable_entity
end

Expand All @@ -64,22 +68,13 @@ def register
def install
end

# GET /udid/qrcode
def qrcode
render qrcode: udid_index_url, **qrcode_options
end

private

def set_device_xml
body = request.body.read

p7sign = OpenSSL::PKCS7.new(body)
store = OpenSSL::X509::Store.new
p7sign.verify(nil, store, nil, OpenSSL::PKCS7::NOVERIFY)

@device_attrs = Plist.parse_xml(p7sign.data)
end

def render_profile
enable_tls = params[:tls] == 'true'
preview = params[:preview] == 'true'
Expand All @@ -96,56 +91,14 @@ def render_profile
render plain: sigend.to_der, content_type: content_type, layout: false
end

def certificate
@certificate ||= lambda do
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = Random.rand(2**16 - 2) + 1
cert.subject = subject
cert.issuer = issuer
cert.not_before = create_date
cert.not_after = expire_date
cert.public_key = root_key.public_key

cert_ext = OpenSSL::X509::ExtensionFactory.new
cert_ext.subject_certificate = cert
cert_ext.issuer_certificate = cert
cert.add_extension(cert_ext.create_extension("basicConstraints","CA:TRUE",true))
cert.add_extension(cert_ext.create_extension("keyUsage","keyCertSign, cRLSign", true))
cert.add_extension(cert_ext.create_extension("subjectKeyIdentifier","hash",false))
cert.add_extension(cert_ext.create_extension("authorityKeyIdentifier","keyid:always",false))
cert.sign(root_key, digest)
cert
end.call
end

def subject
@subject ||= OpenSSL::X509::Name.parse("/C=CN/O=tryzealot/OU=zealot/CN=#{Setting.site_title} Self-signed Authority")
end

def issuer
@issuer ||= OpenSSL::X509::Name.parse("/C=CN/O=tryzealot/OU=zealot/CN=#{Setting.site_title}")
end

def root_key
@key ||= OpenSSL::PKey::RSA.generate(2048)
end

def digest
@digest ||= OpenSSL::Digest.new('SHA256')
end

def payload_uuid
@payload_uuid ||= Rails.cache.fetch('ios-udid', expires_in: 1.week) { SecureRandom.uuid.upcase }
end
def set_device_xml
body = request.body.read

def create_date
Time.now.utc
end
p7sign = OpenSSL::PKCS7.new(body)
store = OpenSSL::X509::Store.new
p7sign.verify(nil, store, nil, OpenSSL::PKCS7::NOVERIFY)

def expire_date
expire_time = 1 * 365 * 24 * 60 * 60 # 1 year
create_date + expire_time
@device_attrs = Plist.parse_xml(p7sign.data)
end

def set_device_metadata
Expand All @@ -162,13 +115,13 @@ def set_device_metadata
end

def device_status
if @apple_keys
'related_apple_keys'
elsif @all_apple_keys.size > 0
'register_apple_key'
else
'unregister_device'
end
@device_status = if @apple_keys
:registered_device
elsif @all_apple_keys.size > 0
:new_register_device
else
:new_device
end
end

def set_apple_key
Expand All @@ -177,6 +130,6 @@ def set_apple_key
end

def device_params
params.require(:device).permit(:name, :sync_to_apple_key)
params.require(:device).permit(:name, :apple_keys, :sync_to_apple_key)
end
end
8 changes: 5 additions & 3 deletions app/models/apple_key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def sync_devices
response_devices = client.devices.all_pages(flatten: true)
logger.debug "Got #{response_devices.size} devices from apple key #{id}"
response_devices.each do |response_device|
logger.debug "Device is: #{response_device.attributes}"
Device.create_from_api(response_device) do |device|
devices << device unless devices.exists?(device.id)
end
Expand All @@ -52,7 +51,9 @@ def sync_devices
end

def register_device(udid, name = nil)
return device if (device = Device.find_by(udid: udid))
if (existed_device = Device.find_by(udid: udid))
return existed_device
end

response_device = client.create_device(udid, name).to_model
Device.create_from_api(response_device) do |device|
Expand Down Expand Up @@ -82,6 +83,7 @@ def register_device(udid, name = nil)
self
rescue => e
logger.error "Register device raise an exception: #{e}"
logger.error e.backtrace.join("\n")

message = e.respond_to?(:errors) ? errors[0]['detail'] : e.message
errors.add(:devices, :unknown, message: message)
Expand All @@ -90,7 +92,7 @@ def register_device(udid, name = nil)
end

def update_device_name(device)
response_device = client.rename_device(device.udid, device.name)
response_device = client.rename_device(device.name, id: device.device_id, udid: device.udid)
rescue TinyAppstoreConnect::InvalidEntityError => e
logger.error "Device may not exists or the other error in apple key #{id}: #{e}"
end
Expand Down
2 changes: 2 additions & 0 deletions app/models/apple_team.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
class AppleTeam < ApplicationRecord
belongs_to :key, class_name: 'AppleKey', foreign_key: 'apple_key_id'

scope :all_names, -> { all.map { |c| ["#{c.display_name} - #{c.team_id}", c.apple_key_id] } }

validates :apple_key_id, :team_id, :name, presence: true
before_save :generate_display_name

Expand Down
1 change: 1 addition & 0 deletions app/models/device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Device < ApplicationRecord
def self.create_from_api(response)
current_udid = response.udid
record_data = {
device_id: response.id,
name: response.name,
model: response.device,
platform: response.platform,
Expand Down
11 changes: 5 additions & 6 deletions app/views/admin/apple_keys/show.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ ruby:
td = device.channels.count
td = device.created_at
.card-footer
p
- if @apple_key.last_synced_at.present?
span title="#{@apple_key.last_synced_at}" data-toggle="tooltip"
= t('.last_synced_at', time: time_ago_in_words(@apple_key.last_synced_at))
- else
= t('.never_sync')
- if @apple_key.last_synced_at.present?
span title="#{@apple_key.last_synced_at}" data-toggle="tooltip"
= t('.last_synced_at', time: time_ago_in_words(@apple_key.last_synced_at))
- else
= t('.never_sync')
6 changes: 3 additions & 3 deletions app/views/udid/_apple_keys.html.slim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
- if (result != 'unregister_device' || apple_keys.present?)
- if (result != 'new_device' || apple_keys.present?)
.col-md-12
- unless apple_keys.empty?
.card.system_info
Expand All @@ -11,13 +11,13 @@
tr
th = t('udid.show.team_name')
th = t('udid.show.team_id')
- if result == 'register_apple_key'
- if result == 'new_register_device'
th = t('udid.show.action')
- apple_keys.each do |apple_key|
tr
td = apple_key.team.full_name
td = apple_key.team.team_id
- if result == 'register_apple_key'
- if result == 'new_register_device'
ruby:
register_link = register_udid_path(udid: params[:udid], apple_key_id: apple_key.id, product: params[:product])
td = button_to t('udid.show.register_device'), register_link, class: 'btn btn-sm btn-success'
Expand Down
File renamed without changes.
19 changes: 10 additions & 9 deletions app/views/udid/_item.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ ruby:
dt = title
dd.input-group.mb-3 data-controller="clipboard-center"
input.form-control.rounded-0 value="#{value}" readonly="true" data-clipboard-center-target="source"
span.input-group-append
button.btn.btn-primary.btn-flat.btn-clipboard[
data-clipboard-center-target="button"
data-action="clipboard-center#copy"
data-clipboard-text="#{value}"
data-toggle="tooltip"
title="Copy me"
]
i.far.fa-clipboard
- if copy.present?
span.input-group-append
button.btn.btn-primary.btn-flat.btn-clipboard[
data-clipboard-center-target="button"
data-action="clipboard-center#copy"
data-clipboard-text="#{value}"
data-toggle="tooltip"
title="Copy me"
]
i.far.fa-clipboard
12 changes: 12 additions & 0 deletions app/views/udid/_new_device.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.row
.col-md-12
.alert.alert-warning
strong Ta-Da!
= t('udid.show.unregistered')

== render 'dashboards/widget', title: t('udid.show.channels'), count: @channel_total, url: '', color_style: 'bg-navy', icon: 'fab fa-adn'
== render 'dashboards/widget', title: t('udid.show.releases'), count: @release_total, url: '', color_style: 'bg-pink', icon: 'fab fa-gg'
== render 'dashboards/widget', title: t('udid.show.apple_keys'), count: @apple_key_total, url: '', color_style: 'bg-yellow', icon: 'fas fa-key'

== render 'udid/udid_metadata', device: @device
== render 'udid/apps', device: @device, channels: @channels
11 changes: 11 additions & 0 deletions app/views/udid/_new_register_device.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.row
.col-md-12
.alert.alert-primary
strong Yah-ah!
= t('udid.show.register')

- if @device.blank?
== render 'udid/register_form', udid: params[:udid], product: params[:product]

== render 'udid/udid_metadata', device: @device
== render 'udid/apps', device: @device, channels: @channels
14 changes: 14 additions & 0 deletions app/views/udid/_register_form.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.col-md-12
.card
= simple_form_for(Device.new, url: register_udid_path(udid: udid, product: product)) do |f|
.card-header
h3.card-title
= t("udid.show.register_device")
.card-tools
.card-body
= f.error_notification
= f.input :name
= f.input :apple_keys, collection: AppleTeam.all_names, label_method: :first, value_method: :last, include_blank: false

.card-footer
= f.button :submit, t('udid.show.register_device')
Loading

0 comments on commit 84e9ae8

Please sign in to comment.