getting_started_controller.rb 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. # Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
  2. require 'resolv'
  3. class GettingStartedController < ApplicationController
  4. =begin
  5. Resource:
  6. GET /api/v1/getting_started
  7. Response:
  8. {
  9. "master_user": 1,
  10. "groups": [
  11. {
  12. "name": "group1",
  13. "active":true
  14. },
  15. {
  16. "name": "group2",
  17. "active":true
  18. }
  19. ]
  20. }
  21. Test:
  22. curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
  23. =end
  24. def index
  25. # check if first user already exists
  26. return if setup_done_response
  27. # if master user already exists, we need to be authenticated
  28. if setup_done
  29. return if !authentication_check
  30. end
  31. # get all groups
  32. groups = Group.where( :active => true )
  33. # return result
  34. render :json => {
  35. :setup_done => setup_done,
  36. :import_mode => Setting.get('import_mode'),
  37. :import_backend => Setting.get('import_backend'),
  38. :groups => groups,
  39. }
  40. end
  41. def base
  42. # check admin permissions
  43. return if deny_if_not_role('Admin')
  44. # validate url
  45. messages = {}
  46. if !params[:url] ||params[:url] !~ /^(http|https):\/\/.+?$/
  47. messages[:url] = 'A URL looks like http://zammad.example.com'
  48. end
  49. # validate organization
  50. if !params[:organization] || params[:organization].empty?
  51. messages[:organization] = 'Invalid!'
  52. end
  53. # validate image
  54. if params[:logo] && params[:logo] =~ /^data:image/i
  55. file = StaticAssets.data_url_attributes( params[:logo] )
  56. if !file[:content] || !file[:content_type]
  57. messages[:logo] = 'Unable to process image upload.'
  58. end
  59. end
  60. if !messages.empty?
  61. render :json => {
  62. :result => 'invalid',
  63. :messages => messages,
  64. }
  65. return
  66. end
  67. # split url in http_type and fqdn
  68. settings = {}
  69. if params[:url] =~ /^(http|https):\/\/(.+?)$/
  70. Setting.set('http_type', $1)
  71. settings[:http_type] = $1
  72. Setting.set('fqdn', $2)
  73. settings[:fqdn] = $2
  74. end
  75. # save organization
  76. Setting.set('organization', params[:organization])
  77. settings[:organization] = params[:organization]
  78. # save image
  79. if params[:logo] && params[:logo] =~ /^data:image/i
  80. # data:image/png;base64
  81. file = StaticAssets.data_url_attributes( params[:logo] )
  82. # store image 1:1
  83. StaticAssets.store_raw( file[:content], file[:content_type] )
  84. end
  85. if params[:logo_resize] && params[:logo_resize] =~ /^data:image/i
  86. # data:image/png;base64
  87. file = StaticAssets.data_url_attributes( params[:logo_resize] )
  88. # store image 1:1
  89. settings[:product_logo] = StaticAssets.store( file[:content], file[:content_type] )
  90. end
  91. # set changed settings
  92. settings.each {|key, value|
  93. Setting.set(key, value)
  94. }
  95. render :json => {
  96. :result => 'ok',
  97. :settings => settings,
  98. }
  99. end
  100. def email_probe
  101. # check admin permissions
  102. return if deny_if_not_role('Admin')
  103. # validation
  104. user = nil
  105. domain = nil
  106. if params[:email] =~ /^(.+?)@(.+?)$/
  107. user = $1
  108. domain = $2
  109. end
  110. if !user || !domain
  111. render :json => {
  112. :result => 'invalid',
  113. :messages => {
  114. :email => 'Invalid email.'
  115. },
  116. }
  117. return
  118. end
  119. # check domain based attributes
  120. providerMap = {
  121. :google => {
  122. :domain => 'gmail.com|googlemail.com|gmail.de',
  123. :inbound => {
  124. :adapter => 'imap',
  125. :options => {
  126. :host => 'imap.gmail.com',
  127. :port => '993',
  128. :ssl => true,
  129. :user => params[:email],
  130. :password => params[:password],
  131. },
  132. },
  133. :outbound => {
  134. :adapter => 'smtp',
  135. :options => {
  136. :host => 'smtp.gmail.com',
  137. :port => '25',
  138. :ssl => true,
  139. :user => params[:email],
  140. :password => params[:password],
  141. }
  142. },
  143. },
  144. }
  145. # probe based on email domain and mx
  146. domains = [domain]
  147. mail_exchangers = mxers(domain)
  148. if mail_exchangers && mail_exchangers[0]
  149. logger.info "MX for #{domain}: #{mail_exchangers} - #{mail_exchangers[0][0]}"
  150. end
  151. if mail_exchangers && mail_exchangers[0] && mail_exchangers[0][0]
  152. domains.push mail_exchangers[0][0]
  153. end
  154. providerMap.each {|provider, settings|
  155. domains.each {|domain_to_check|
  156. if domain_to_check =~ /#{settings[:domain]}/i
  157. # probe inbound
  158. result = email_probe_inbound( settings[:inbound] )
  159. if result[:result] != 'ok'
  160. render :json => result
  161. return
  162. end
  163. # probe outbound
  164. result = email_probe_outbound( settings[:outbound], params[:email] )
  165. if result[:result] != 'ok'
  166. render :json => result
  167. return
  168. end
  169. render :json => {
  170. :result => 'ok',
  171. :setting => settings,
  172. }
  173. return
  174. end
  175. }
  176. }
  177. # probe inbound
  178. inboundMap = []
  179. if mail_exchangers && mail_exchangers[0] && mail_exchangers[0][0]
  180. inboundMx = [
  181. {
  182. :adapter => 'imap',
  183. :options => {
  184. :host => mail_exchangers[0][0],
  185. :port => 993,
  186. :ssl => true,
  187. :user => user,
  188. :password => params[:password],
  189. },
  190. },
  191. {
  192. :adapter => 'imap',
  193. :options => {
  194. :host => mail_exchangers[0][0],
  195. :port => 993,
  196. :ssl => true,
  197. :user => params[:email],
  198. :password => params[:password],
  199. },
  200. },
  201. ]
  202. inboundMap = inboundMap + inboundMx
  203. end
  204. inboundAuto = [
  205. {
  206. :adapter => 'imap',
  207. :options => {
  208. :host => "mail.#{domain}",
  209. :port => 993,
  210. :ssl => true,
  211. :user => user,
  212. :password => params[:password],
  213. },
  214. },
  215. {
  216. :adapter => 'imap',
  217. :options => {
  218. :host => "mail.#{domain}",
  219. :port => 993,
  220. :ssl => true,
  221. :user => params[:email],
  222. :password => params[:password],
  223. },
  224. },
  225. {
  226. :adapter => 'imap',
  227. :options => {
  228. :host => "imap.#{domain}",
  229. :port => 993,
  230. :ssl => true,
  231. :user => user,
  232. :password => params[:password],
  233. },
  234. },
  235. {
  236. :adapter => 'imap',
  237. :options => {
  238. :host => "imap.#{domain}",
  239. :port => 993,
  240. :ssl => true,
  241. :user => params[:email],
  242. :password => params[:password],
  243. },
  244. },
  245. {
  246. :adapter => 'pop3',
  247. :options => {
  248. :host => "mail.#{domain}",
  249. :port => 995,
  250. :ssl => true,
  251. :user => user,
  252. :password => params[:password],
  253. },
  254. },
  255. {
  256. :adapter => 'pop3',
  257. :options => {
  258. :host => "mail.#{domain}",
  259. :port => 995,
  260. :ssl => true,
  261. :user => params[:email],
  262. :password => params[:password],
  263. },
  264. },
  265. {
  266. :adapter => 'pop3',
  267. :options => {
  268. :host => "pop.#{domain}",
  269. :port => 995,
  270. :ssl => true,
  271. :user => user,
  272. :password => params[:password],
  273. },
  274. },
  275. {
  276. :adapter => 'pop3',
  277. :options => {
  278. :host => "pop.#{domain}",
  279. :port => 995,
  280. :ssl => true,
  281. :user => params[:email],
  282. :password => params[:password],
  283. },
  284. },
  285. {
  286. :adapter => 'pop3',
  287. :options => {
  288. :host => "pop3.#{domain}",
  289. :port => 995,
  290. :ssl => true,
  291. :user => user,
  292. :password => params[:password],
  293. },
  294. },
  295. {
  296. :adapter => 'pop3',
  297. :options => {
  298. :host => "pop3.#{domain}",
  299. :port => 995,
  300. :ssl => true,
  301. :user => params[:email],
  302. :password => params[:password],
  303. },
  304. },
  305. ]
  306. inboundMap = inboundMap + inboundAuto
  307. settings = {}
  308. success = false
  309. inboundMap.each {|config|
  310. logger.info "INBOUND PROBE: #{config.inspect}"
  311. result = email_probe_inbound( config )
  312. logger.info "INBOUND RESULT: #{result.inspect}"
  313. if result[:result] == 'ok'
  314. success = true
  315. settings[:inbound] = config
  316. break
  317. end
  318. }
  319. if !success
  320. render :json => {
  321. :result => 'failed',
  322. }
  323. return
  324. end
  325. # probe outbound
  326. outboundMap = []
  327. if mail_exchangers && mail_exchangers[0] && mail_exchangers[0][0]
  328. outboundMx = [
  329. {
  330. :adapter => 'smtp',
  331. :options => {
  332. :host => mail_exchangers[0][0],
  333. :port => 25,
  334. :ssl => true,
  335. :user => user,
  336. :password => params[:password],
  337. },
  338. },
  339. {
  340. :adapter => 'smtp',
  341. :options => {
  342. :host => mail_exchangers[0][0],
  343. :port => 25,
  344. :ssl => true,
  345. :user => params[:email],
  346. :password => params[:password],
  347. },
  348. },
  349. {
  350. :adapter => 'smtp',
  351. :options => {
  352. :host => mail_exchangers[0][0],
  353. :port => 465,
  354. :ssl => true,
  355. :user => user,
  356. :password => params[:password],
  357. },
  358. },
  359. {
  360. :adapter => 'smtp',
  361. :options => {
  362. :host => mail_exchangers[0][0],
  363. :port => 465,
  364. :ssl => true,
  365. :user => params[:email],
  366. :password => params[:password],
  367. },
  368. },
  369. ]
  370. outboundMap = outboundMap + outboundMx
  371. end
  372. outboundAuto = [
  373. {
  374. :adapter => 'smtp',
  375. :options => {
  376. :host => "mail.#{domain}",
  377. :port => 25,
  378. :ssl => true,
  379. :user => user,
  380. :password => params[:password],
  381. },
  382. },
  383. {
  384. :adapter => 'smtp',
  385. :options => {
  386. :host => "mail.#{domain}",
  387. :port => 25,
  388. :ssl => true,
  389. :user => params[:email],
  390. :password => params[:password],
  391. },
  392. },
  393. {
  394. :adapter => 'smtp',
  395. :options => {
  396. :host => "mail.#{domain}",
  397. :port => 465,
  398. :ssl => true,
  399. :user => user,
  400. :password => params[:password],
  401. },
  402. },
  403. {
  404. :adapter => 'smtp',
  405. :options => {
  406. :host => "mail.#{domain}",
  407. :port => 465,
  408. :ssl => true,
  409. :user => params[:email],
  410. :password => params[:password],
  411. },
  412. },
  413. {
  414. :adapter => 'smtp',
  415. :options => {
  416. :host => "smtp.#{domain}",
  417. :port => 25,
  418. :ssl => true,
  419. :user => user,
  420. :password => params[:password],
  421. },
  422. },
  423. {
  424. :adapter => 'smtp',
  425. :options => {
  426. :host => "smtp.#{domain}",
  427. :port => 25,
  428. :ssl => true,
  429. :user => params[:email],
  430. :password => params[:password],
  431. },
  432. },
  433. {
  434. :adapter => 'smtp',
  435. :options => {
  436. :host => "smtp.#{domain}",
  437. :port => 465,
  438. :ssl => true,
  439. :user => user,
  440. :password => params[:password],
  441. },
  442. },
  443. {
  444. :adapter => 'smtp',
  445. :options => {
  446. :host => "smtp.#{domain}",
  447. :port => 465,
  448. :ssl => true,
  449. :user => params[:email],
  450. :password => params[:password],
  451. },
  452. },
  453. ]
  454. success = false
  455. outboundMap.each {|config|
  456. logger.info "OUTBOUND PROBE: #{config.inspect}"
  457. result = email_probe_outbound( config, params[:email] )
  458. logger.info "OUTBOUND RESULT: #{result.inspect}"
  459. if result[:result] == 'ok'
  460. success = true
  461. settings[:outbound] = config
  462. break
  463. end
  464. }
  465. if !success
  466. render :json => {
  467. :result => 'failed',
  468. }
  469. return
  470. end
  471. render :json => {
  472. :result => 'ok',
  473. :setting => settings,
  474. }
  475. end
  476. def email_outbound
  477. # check admin permissions
  478. return if deny_if_not_role('Admin')
  479. # validate params
  480. if !params[:adapter]
  481. render :json => {
  482. :result => 'invalid',
  483. }
  484. return
  485. end
  486. # connection test
  487. result = email_probe_outbound( params, params[:email] )
  488. render :json => result
  489. end
  490. def email_inbound
  491. # check admin permissions
  492. return if deny_if_not_role('Admin')
  493. # validate params
  494. if !params[:adapter]
  495. render :json => {
  496. :result => 'invalid',
  497. }
  498. return
  499. end
  500. # connection test
  501. result = email_probe_inbound( params )
  502. render :json => result
  503. return
  504. end
  505. def email_verify
  506. # check admin permissions
  507. return if deny_if_not_role('Admin')
  508. # send verify email to inbox
  509. if !params[:subject]
  510. subject = '#' + rand(99999999999).to_s
  511. else
  512. subject = params[:subject]
  513. end
  514. result = email_probe_outbound( params[:outbound], params[:meta][:email], subject )
  515. (1..5).each {|loop|
  516. sleep 10
  517. # fetch mailbox
  518. found = nil
  519. begin
  520. if params[:inbound][:adapter] =~ /^imap$/i
  521. found = Channel::IMAP.new.fetch( { :options => params[:inbound][:options] }, 'verify', subject )
  522. else
  523. found = Channel::POP3.new.fetch( { :options => params[:inbound][:options] }, 'verify', subject )
  524. end
  525. rescue Exception => e
  526. render :json => {
  527. :result => 'invalid',
  528. :message => e.to_s,
  529. :subject => subject,
  530. }
  531. return
  532. end
  533. if found && found == 'verify ok'
  534. # remember address
  535. address = EmailAddress.all.first
  536. if address
  537. address.update_attributes(
  538. :realname => params[:meta][:realname],
  539. :email => params[:meta][:email],
  540. :active => 1,
  541. :updated_by_id => 1,
  542. :created_by_id => 1,
  543. )
  544. else
  545. EmailAddress.create(
  546. :realname => params[:meta][:realname],
  547. :email => params[:meta][:email],
  548. :active => 1,
  549. :updated_by_id => 1,
  550. :created_by_id => 1,
  551. )
  552. end
  553. # store mailbox
  554. Channel.create(
  555. :area => 'Email::Inbound',
  556. :adapter => params[:inbound][:adapter],
  557. :options => params[:inbound][:options],
  558. :group_id => 1,
  559. :active => 1,
  560. :updated_by_id => 1,
  561. :created_by_id => 1,
  562. )
  563. # save settings
  564. if params[:outbound][:adapter] =~ /^smtp$/i
  565. smtp = Channel.where( :adapter => 'SMTP', :area => 'Email::Outbound' ).first
  566. smtp.options = params[:outbound][:options]
  567. smtp.active = true
  568. smtp.save!
  569. sendmail = Channel.where( :adapter => 'Sendmail' ).first
  570. sendmail.active = false
  571. sendmail.save!
  572. else
  573. sendmail = Channel.where( :adapter => 'Sendmail', :area => 'Email::Outbound' ).first
  574. sendmail.options = {}
  575. sendmail.active = true
  576. sendmail.save!
  577. smtp = Channel.where( :adapter => 'SMTP' ).first
  578. smtp.active = false
  579. smtp.save
  580. end
  581. render :json => {
  582. :result => 'ok',
  583. }
  584. return
  585. end
  586. }
  587. # check delivery for 30 sek.
  588. render :json => {
  589. :result => 'invalid',
  590. :message => 'Verification Email not found in mailbox.',
  591. :subject => subject,
  592. }
  593. end
  594. private
  595. def email_probe_outbound(params, email, subject = nil)
  596. # validate params
  597. if !params[:adapter]
  598. result = {
  599. :result => 'invalid',
  600. :message => 'Invalid, need adapter!',
  601. }
  602. return result
  603. end
  604. if subject
  605. mail = {
  606. :from => email,
  607. :to => email,
  608. :subject => "Zammad Getting started Test Email #{subject}",
  609. :body => '.',
  610. 'x-zammad-ignore' => 'true',
  611. }
  612. else
  613. mail = {
  614. :from => email,
  615. :to => 'emailtrytest@znuny.com',
  616. :subject => 'test',
  617. :body => 'test',
  618. }
  619. end
  620. # test connection
  621. translationMap = {
  622. 'authentication failed' => 'Authentication failed!',
  623. 'Incorrect username' => 'Authentication failed!',
  624. 'getaddrinfo: nodename nor servname provided, or not known' => 'Hostname not found!',
  625. 'No route to host' => 'No route to host!',
  626. 'Connection refused' => 'Connection refused!',
  627. }
  628. if params[:adapter] =~ /^smtp$/i
  629. # in case, fill missing params
  630. if !params[:options].has_key?(:port)
  631. params[:options][:port] = 25
  632. end
  633. if !params[:options].has_key?(:ssl)
  634. params[:options][:ssl] = true
  635. end
  636. begin
  637. Channel::SMTP.new.send(
  638. mail,
  639. {
  640. :options => params[:options]
  641. }
  642. )
  643. rescue Exception => e
  644. # check if sending email was ok, but mailserver rejected
  645. if !subject
  646. whiteMap = {
  647. 'Recipient address rejected' => true,
  648. }
  649. whiteMap.each {|key, message|
  650. if e.message =~ /#{Regexp.escape(key)}/i
  651. result = {
  652. :result => 'ok',
  653. :settings => params,
  654. :notice => e.message,
  655. }
  656. return result
  657. end
  658. }
  659. end
  660. message_human = ''
  661. translationMap.each {|key, message|
  662. if e.message =~ /#{Regexp.escape(key)}/i
  663. message_human = message
  664. end
  665. }
  666. result = {
  667. :result => 'invalid',
  668. :settings => params,
  669. :message => e.message,
  670. :message_human => message_human,
  671. }
  672. return result
  673. end
  674. result = {
  675. :result => 'ok',
  676. }
  677. return result
  678. end
  679. begin
  680. Channel::Sendmail.new.send(
  681. mail,
  682. nil
  683. )
  684. rescue Exception => e
  685. message_human = ''
  686. translationMap.each {|key, message|
  687. if e.message =~ /#{Regexp.escape(key)}/i
  688. message_human = message
  689. end
  690. }
  691. result = {
  692. :result => 'invalid',
  693. :settings => params,
  694. :message => e.message,
  695. :message_human => message_human,
  696. }
  697. return result
  698. end
  699. result = {
  700. :result => 'ok',
  701. }
  702. return result
  703. end
  704. def email_probe_inbound(params)
  705. # validate params
  706. if !params[:adapter]
  707. raise 'need :adapter param'
  708. end
  709. # connection test
  710. translationMap = {
  711. 'authentication failed' => 'Authentication failed!',
  712. 'Incorrect username' => 'Authentication failed!',
  713. 'getaddrinfo: nodename nor servname provided, or not known' => 'Hostname not found!',
  714. 'No route to host' => 'No route to host!',
  715. 'Connection refused' => 'Connection refused!',
  716. }
  717. if params[:adapter] =~ /^imap$/i
  718. begin
  719. Channel::IMAP.new.fetch( { :options => params[:options] }, 'check' )
  720. rescue Exception => e
  721. message_human = ''
  722. translationMap.each {|key, message|
  723. if e.message =~ /#{Regexp.escape(key)}/i
  724. message_human = message
  725. end
  726. }
  727. result = {
  728. :result => 'invalid',
  729. :settings => params,
  730. :message => e.message,
  731. :message_human => message_human,
  732. }
  733. return result
  734. end
  735. result = {
  736. :result => 'ok',
  737. }
  738. return result
  739. end
  740. begin
  741. Channel::POP3.new.fetch( { :options => params[:options] }, 'check' )
  742. rescue Exception => e
  743. message_human = ''
  744. translationMap.each {|key, message|
  745. if e.message =~ /#{Regexp.escape(key)}/i
  746. message_human = message
  747. end
  748. }
  749. result = {
  750. :result => 'invalid',
  751. :settings => params,
  752. :message => e.message,
  753. :message_human => message_human,
  754. }
  755. return result
  756. end
  757. result = {
  758. :result => 'ok',
  759. }
  760. return result
  761. end
  762. def mxers(domain)
  763. mxs = Resolv::DNS.open do |dns|
  764. ress = dns.getresources(domain, Resolv::DNS::Resource::IN::MX)
  765. ress.map { |r| [r.exchange.to_s, IPSocket::getaddress(r.exchange.to_s), r.preference] }
  766. end
  767. mxs
  768. end
  769. def setup_done
  770. #return false
  771. count = User.all.count()
  772. done = true
  773. if count <= 2
  774. done = false
  775. end
  776. done
  777. end
  778. def setup_done_response
  779. if !setup_done
  780. return false
  781. end
  782. render :json => {
  783. :setup_done => true,
  784. :import_mode => Setting.get('import_mode'),
  785. :import_backend => Setting.get('import_backend'),
  786. }
  787. true
  788. end
  789. end