Class: Socialcast::CLI

Inherits:
Thor
  • Object
show all
Includes:
Thor::Actions
Defined in:
lib/socialcast/cli.rb

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ CLI

Returns a new instance of CLI.



39
# File 'lib/socialcast/cli.rb', line 39

def initialize(*args); super(*args) end

Instance Method Details

#authenticateObject



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/socialcast/cli.rb', line 46

def authenticate
  user = options[:user] || ask('Socialcast username: ')
  password = options[:password] || HighLine.new.ask("Socialcast password: ") { |q| q.echo = false }.to_s
  domain = options[:domain]

  url = ['https://', domain, '/api/authentication'].join
  say "Authenticating #{user} to #{url}"
  params = {:email => user, :password => password }
  RestClient.log = Logger.new(STDOUT) if options[:trace]
  RestClient.proxy = options[:proxy] if options[:proxy]
  resource = RestClient::Resource.new url
  response = resource.post params, :accept => :json
  say "API response: #{response.body.to_s}" if options[:trace]
  communities = JSON.parse(response.body.to_s)['communities']
  domain = communities.detect {|c| c['domain'] == domain} ? domain : communities.first['domain']

  Socialcast.credentials = {:user => user, :password => password, :domain => domain, :proxy => options[:proxy]}
  say "Authentication successful for #{domain}"
end

#provisionObject



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/socialcast/cli.rb', line 106

def provision
  config = ldap_config options
  load_plugins options

  http_config = config.fetch 'http', {}
  mappings = config.fetch 'mappings', {}
  permission_mappings = config.fetch 'permission_mappings', {}

  user_identifier_list = %w{email unique_identifier employee_number}
  user_whitelist = Set.new
  output_file = File.join Dir.pwd, options[:output]

  Zlib::GzipWriter.open(output_file) do |gz|
    xml = Builder::XmlMarkup.new(:target => gz, :indent => 1)
    xml.instruct!
    xml.export do |export|
      export.users(:type => "array") do |users|
        each_ldap_entry(config) do |ldap, entry|
          users.user do |user|
            entry.build_xml_from_mappings user, ldap, mappings, permission_mappings
          end
          user_whitelist << user_identifier_list.map { |identifier| entry.grab(mappings[identifier]) }
        end # connections
      end # users
    end # export
  end # gzip

  if options[:sanity_check]
    say "Sanity checking users currently marked as needing to be terminated"
    ldap_connections(config) do |key, connection, ldap|
      (current_socialcast_users(http_config) - user_whitelist).each do |user_identifiers|
        combined_filters = []
        user_identifier_list.each_with_index do |identifier, index|
          combined_filters << ((mappings[identifier].blank? || user_identifiers[index].nil?) ? nil : Net::LDAP::Filter.eq(mappings[identifier], user_identifiers[index]))
        end
        combined_filters.compact!
        filter = ((combined_filters.size > 1) ? '(|%s)' : '%s') % combined_filters.join(' ')
        filter = Net::LDAP::Filter.construct(filter) & Net::LDAP::Filter.construct(connection["filter"])
        ldap_result = ldap.search(:return_result => true, :base => connection["basedn"], :filter => filter, :attributes => ldap_search_attributes(config))
        Kernel.abort("Found user marked for termination that should not be terminated: #{user_identifiers}") unless ldap_result.blank?
      end
    end
  end

  if user_whitelist.empty? && !options[:force]
    Kernel.abort("Skipping upload to Socialcast since no users were found")
  else
    say "Uploading dataset to Socialcast..."
    resource = Socialcast.resource_for_path '/api/users/provision', http_config
    begin
      File.open(output_file, 'r') do |file|
        request_params = {:file => file}
        request_params[:skip_emails] = 'true' if (config['options']["skip_emails"] || options[:skip_emails])
        request_params[:test] = 'true' if (config['options']["test"] || options[:test])
        resource.post request_params, :accept => :json
      end
    rescue RestClient::Unauthorized => e
      Kernel.abort "Authenticated user either does not have administration privileges or the community is not configured to allow provisioning. Please contact Socialcast support to if you need help." if e.http_code == 401
    end
    say "Finished"
  end
  File.delete(output_file) if (config['options']['delete_users_file'] || options[:delete_users_file])
end

#share(message = nil) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/socialcast/cli.rb', line 71

def share(message = nil)
  message ||= $stdin.read_nonblock(100_000) rescue nil

  attachment_ids = []
  options[:attachments].each do |path|
    Dir[File.expand_path(path)].each do |attachment|
      say "Uploading attachment #{attachment}..."
      uploader = Socialcast.resource_for_path '/api/attachments', {}, options[:trace]
      uploader.post({:attachment => File.new(attachment)}, {:accept => :json}) do |response, request, result|
        if response.code == 201
          attachment_ids << JSON.parse(response.body)['attachment']['id']
        else
          say "Error uploading attachment: #{response.body}"
        end
      end
    end
  end

  ActiveResource::Base.logger = Logger.new(STDOUT) if options[:trace]
  Socialcast::Message.configure_from_credentials
  Socialcast::Message.create :body => message, :url => options[:url], :message_type => options[:message_type], :attachment_ids => attachment_ids, :group_id => options[:group_id]

  say "Message has been shared"
end

#sync_photosObject



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/socialcast/cli.rb', line 172

def sync_photos
  config = ldap_config options
  http_config = config.fetch 'http', {}
  mappings = config.fetch 'mappings', {}
  profile_photo_field = mappings.fetch('profile_photo')

  search_users_resource = Socialcast.resource_for_path '/api/users/search', http_config

  each_ldap_entry(config) do |ldap, entry|
    email = entry.grab(mappings['email'])
    if profile_photo_data = entry.grab(mappings['profile_photo'])
      profile_photo_data = profile_photo_data.force_encoding('binary')

      user_search_response = search_users_resource.get(:params => { :q => email, :per_page => 1 }, :accept => :json)
       = JSON.parse(user_search_response)['users'].first
      if  && ['avatars'] && ['avatars']['is_system_default']
        say "Uploading photo for #{email}"

        user_resource = Socialcast.resource_for_path "/api/users/#{['id']}", http_config
        content_type = case profile_photo_data
        when Regexp.new("\AGIF8", nil, 'n')
          'gif'
        when Regexp.new('\A\x89PNG', nil, 'n')
          'png'
        when Regexp.new("\A\xff\xd8\xff\xe0\x00\x10JFIF", nil, 'n'), Regexp.new("\A\xff\xd8\xff\xe1(.*){2}Exif", nil, 'n')
          'jpg'
        else
          say "Skipping photo for #{email}: unknown image format (supports .gif, .png, .jpg)"
          next
        end

        tempfile = Tempfile.new(["photo_upload", ".#{content_type}"])
        tempfile.write(profile_photo_data)
        tempfile.rewind
        begin
          user_resource.put({ :user => { :profile_photo => { :data => tempfile } } })
        ensure
          tempfile.unlink
        end
      end
    end

  end
end