users_controller.rb 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029
  1. # Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
  2. class UsersController < ApplicationController
  3. before_action :authentication_check, except: [:create, :password_reset_send, :password_reset_verify, :image]
  4. # @path [GET] /users
  5. #
  6. # @summary Returns a list of User records.
  7. # @notes The requester has to be in the role 'Admin' or 'Agent' to
  8. # get a list of all Users. If the requester is in the
  9. # role 'Customer' only just the own User record will be returned.
  10. #
  11. # @response_message 200 [Array<User>] List of matching User records.
  12. # @response_message 401 Invalid session.
  13. def index
  14. offset = 0
  15. per_page = 500
  16. if params[:page] && params[:per_page]
  17. offset = (params[:page].to_i - 1) * params[:per_page].to_i
  18. per_page = params[:per_page].to_i
  19. end
  20. if per_page > 500
  21. per_page = 500
  22. end
  23. # only allow customer to fetch him self
  24. users = if !current_user.permissions?('admin.user') && !current_user.permissions?('ticket.agent')
  25. User.where(id: current_user.id).offset(offset).limit(per_page)
  26. else
  27. User.all.offset(offset).limit(per_page)
  28. end
  29. if params[:expand]
  30. list = []
  31. users.each { |user|
  32. list.push user.attributes_with_relation_names
  33. }
  34. render json: list, status: :ok
  35. return
  36. end
  37. if params[:full]
  38. assets = {}
  39. item_ids = []
  40. users.each { |item|
  41. item_ids.push item.id
  42. assets = item.assets(assets)
  43. }
  44. render json: {
  45. record_ids: item_ids,
  46. assets: assets,
  47. }, status: :ok
  48. return
  49. end
  50. users_all = []
  51. users.each { |user|
  52. users_all.push User.lookup(id: user.id).attributes_with_associations
  53. }
  54. render json: users_all, status: :ok
  55. end
  56. # @path [GET] /users/{id}
  57. #
  58. # @summary Returns the User record with the requested identifier.
  59. # @notes The requester has to be in the role 'Admin' or 'Agent' to
  60. # access all User records. If the requester is in the
  61. # role 'Customer' just the own User record is accessable.
  62. #
  63. # @parameter id(required) [Integer] The identifier matching the requested User.
  64. # @parameter full [Bool] If set a Asset structure with all connected Assets gets returned.
  65. #
  66. # @response_message 200 [User] User record matching the requested identifier.
  67. # @response_message 401 Invalid session.
  68. def show
  69. # access deny
  70. permission_check_local
  71. if params[:expand]
  72. user = User.find(params[:id]).attributes_with_relation_names
  73. render json: user, status: :ok
  74. return
  75. end
  76. if params[:full]
  77. full = User.full(params[:id])
  78. render json: full
  79. return
  80. end
  81. user = User.find(params[:id]).attributes_with_associations
  82. user.delete('password')
  83. render json: user
  84. end
  85. # @path [POST] /users
  86. #
  87. # @summary Creates a User record with the provided attribute values.
  88. # @notes TODO.
  89. #
  90. # @parameter User(required,body) [User] The attribute value structure needed to create a User record.
  91. #
  92. # @response_message 200 [User] Created User record.
  93. # @response_message 401 Invalid session.
  94. def create
  95. # in case of authentication, set current_user to access later
  96. authentication_check_only({})
  97. clean_params = User.param_association_lookup(params)
  98. clean_params = User.param_cleanup(clean_params, true)
  99. user = User.new(clean_params)
  100. user.param_set_associations(params)
  101. # check if it's first user, the admin user
  102. # inital admin account
  103. count = User.all.count()
  104. admin_account_exists = true
  105. if count <= 2
  106. admin_account_exists = false
  107. end
  108. # if it's a signup, add user to customer role
  109. if !current_user
  110. # check if feature is enabled
  111. if admin_account_exists && !Setting.get('user_create_account')
  112. raise Exceptions::UnprocessableEntity, 'Feature not enabled!'
  113. end
  114. # check signup option only after admin account is created
  115. if admin_account_exists && !params[:signup]
  116. raise Exceptions::UnprocessableEntity, 'Only signup with not authenticate user possible!'
  117. end
  118. user.updated_by_id = 1
  119. user.created_by_id = 1
  120. # add first user as admin/agent and to all groups
  121. group_ids = []
  122. role_ids = []
  123. if count <= 2
  124. Role.where(name: %w(Admin Agent)).each { |role|
  125. role_ids.push role.id
  126. }
  127. Group.all().each { |group|
  128. group_ids.push group.id
  129. }
  130. # everybody else will go as customer per default
  131. else
  132. role_ids = Role.signup_role_ids
  133. end
  134. user.role_ids = role_ids
  135. user.group_ids = group_ids
  136. # remember source (in case show email verify banner)
  137. # if not inital user creation
  138. if admin_account_exists
  139. user.source = 'signup'
  140. end
  141. # else do assignment as defined
  142. else
  143. # permission check
  144. permission_check_by_permission(params)
  145. if params[:role_ids]
  146. user.role_ids = params[:role_ids]
  147. end
  148. if params[:group_ids]
  149. user.group_ids = params[:group_ids]
  150. end
  151. end
  152. # check if user already exists
  153. if user.email
  154. exists = User.where(email: user.email.downcase).first
  155. raise Exceptions::UnprocessableEntity, 'User already exists!' if exists
  156. end
  157. user.save!
  158. # if first user was added, set system init done
  159. if !admin_account_exists
  160. Setting.set('system_init_done', true)
  161. # fetch org logo
  162. if user.email
  163. Service::Image.organization_suggest(user.email)
  164. end
  165. # load calendar
  166. Calendar.init_setup(request.remote_ip)
  167. # load text modules
  168. begin
  169. TextModule.load(request.env['HTTP_ACCEPT_LANGUAGE'] || 'en-us')
  170. rescue => e
  171. logger.error "Unable to load text modules #{request.env['HTTP_ACCEPT_LANGUAGE'] || 'en-us'}: #{e.message}"
  172. end
  173. end
  174. # send inviteation if needed / only if session exists
  175. if params[:invite] && current_user
  176. token = Token.create(action: 'PasswordReset', user_id: user.id)
  177. NotificationFactory::Mailer.notification(
  178. template: 'user_invite',
  179. user: user,
  180. objects: {
  181. token: token,
  182. user: user,
  183. current_user: current_user,
  184. }
  185. )
  186. end
  187. # send email verify
  188. if params[:signup] && !current_user
  189. result = User.signup_new_token(user)
  190. NotificationFactory::Mailer.notification(
  191. template: 'signup',
  192. user: user,
  193. objects: result,
  194. )
  195. end
  196. if params[:expand]
  197. user = User.find(user.id).attributes_with_relation_names
  198. render json: user, status: :created
  199. return
  200. end
  201. user_new = User.find(user.id).attributes_with_associations
  202. user_new.delete('password')
  203. render json: user_new, status: :created
  204. end
  205. # @path [PUT] /users/{id}
  206. #
  207. # @summary Updates the User record matching the identifier with the provided attribute values.
  208. # @notes TODO.
  209. #
  210. # @parameter id(required) [Integer] The identifier matching the requested User record.
  211. # @parameter User(required,body) [User] The attribute value structure needed to update a User record.
  212. #
  213. # @response_message 200 [User] Updated User record.
  214. # @response_message 401 Invalid session.
  215. def update
  216. # access deny
  217. permission_check_local
  218. user = User.find(params[:id])
  219. clean_params = User.param_association_lookup(params)
  220. clean_params = User.param_cleanup(clean_params, true)
  221. # permission check
  222. permission_check_by_permission(params)
  223. user.with_lock do
  224. user.update_attributes(clean_params)
  225. # only allow Admin's
  226. if current_user.permissions?('admin.user') && (params[:role_ids] || params[:roles])
  227. user.role_ids = params[:role_ids]
  228. user.param_set_associations({ role_ids: params[:role_ids], roles: params[:roles] })
  229. end
  230. # only allow Admin's
  231. if current_user.permissions?('admin.user') && (params[:group_ids] || params[:groups])
  232. user.group_ids = params[:group_ids]
  233. user.param_set_associations({ group_ids: params[:group_ids], groups: params[:groups] })
  234. end
  235. # only allow Admin's and Agent's
  236. if current_user.permissions?(['admin.user', 'ticket.agent']) && (params[:organization_ids] || params[:organizations])
  237. user.param_set_associations({ organization_ids: params[:organization_ids], organizations: params[:organizations] })
  238. end
  239. if params[:expand]
  240. user = User.find(user.id).attributes_with_relation_names
  241. render json: user, status: :ok
  242. return
  243. end
  244. end
  245. # get new data
  246. user_new = User.find(user.id).attributes_with_associations
  247. user_new.delete('password')
  248. render json: user_new, status: :ok
  249. end
  250. # @path [DELETE] /users/{id}
  251. #
  252. # @summary Deletes the User record matching the given identifier.
  253. # @notes The requester has to be in the role 'Admin' to be able to delete a User record.
  254. #
  255. # @parameter id(required) [User] The identifier matching the requested User record.
  256. #
  257. # @response_message 200 User successfully deleted.
  258. # @response_message 401 Invalid session.
  259. def destroy
  260. permission_check('admin.user')
  261. model_references_check(User, params)
  262. model_destory_render(User, params)
  263. end
  264. # @path [GET] /users/search
  265. #
  266. # @tag Search
  267. # @tag User
  268. #
  269. # @summary Searches the User matching the given expression(s).
  270. # @notes TODO: It's possible to use the SOLR search syntax.
  271. # The requester has to be in the role 'Admin' or 'Agent' to
  272. # be able to search for User records.
  273. #
  274. # @parameter query [String] The search query.
  275. # @parameter limit [Integer] The limit of search results.
  276. # @parameter role_ids(multi) [Array<String>] A list of Role identifiers to which the Users have to be allocated to.
  277. # @parameter full [Boolean] Defines if the result should be
  278. # true: { user_ids => [1,2,...], assets => {...} }
  279. # or false: [{:id => user.id, :label => "firstname lastname <email>", :value => "firstname lastname <email>"},...].
  280. #
  281. # @response_message 200 [Array<User>] A list of User records matching the search term.
  282. # @response_message 401 Invalid session.
  283. def search
  284. if !current_user.permissions?('ticket.agent') && !current_user.permissions?('admin.user')
  285. response_access_deny
  286. return
  287. end
  288. # set limit for pagination if needed
  289. if params[:page] && params[:per_page]
  290. params[:limit] = params[:page].to_i * params[:per_page].to_i
  291. end
  292. if params[:limit] && params[:limit].to_i > 500
  293. params[:limit].to_i = 500
  294. end
  295. query_params = {
  296. query: params[:query],
  297. limit: params[:limit],
  298. current_user: current_user,
  299. }
  300. if params[:role_ids] && !params[:role_ids].empty?
  301. query_params[:role_ids] = params[:role_ids]
  302. end
  303. # do query
  304. user_all = User.search(query_params)
  305. # do pagination if needed
  306. if params[:page] && params[:per_page]
  307. offset = (params[:page].to_i - 1) * params[:per_page].to_i
  308. user_all = user_all.slice(offset, params[:per_page].to_i) || []
  309. end
  310. if params[:expand]
  311. list = []
  312. user_all.each { |user|
  313. list.push user.attributes_with_relation_names
  314. }
  315. render json: list, status: :ok
  316. return
  317. end
  318. # build result list
  319. if params[:label]
  320. users = []
  321. user_all.each { |user|
  322. realname = user.firstname.to_s + ' ' + user.lastname.to_s
  323. if user.email && user.email.to_s != ''
  324. realname = realname + ' <' + user.email.to_s + '>'
  325. end
  326. a = { id: user.id, label: realname, value: realname }
  327. users.push a
  328. }
  329. # return result
  330. render json: users
  331. return
  332. end
  333. if params[:full]
  334. user_ids = []
  335. assets = {}
  336. user_all.each { |user|
  337. assets = user.assets(assets)
  338. user_ids.push user.id
  339. }
  340. # return result
  341. render json: {
  342. assets: assets,
  343. user_ids: user_ids.uniq,
  344. }
  345. return
  346. end
  347. list = []
  348. user_all.each { |user|
  349. list.push user.attributes
  350. }
  351. render json: list, status: :ok
  352. end
  353. # @path [GET] /users/recent
  354. #
  355. # @tag Search
  356. # @tag User
  357. #
  358. # @summary Recent creates Users.
  359. # @notes Recent creates Users.
  360. #
  361. # @parameter limit [Integer] The limit of search results.
  362. # @parameter role_ids(multi) [Array<String>] A list of Role identifiers to which the Users have to be allocated to.
  363. # @parameter full [Boolean] Defines if the result should be
  364. # true: { user_ids => [1,2,...], assets => {...} }
  365. # or false: [{:id => user.id, :label => "firstname lastname <email>", :value => "firstname lastname <email>"},...].
  366. #
  367. # @response_message 200 [Array<User>] A list of User records matching the search term.
  368. # @response_message 401 Invalid session.
  369. def recent
  370. if !current_user.permissions?('admin.user')
  371. response_access_deny
  372. return
  373. end
  374. # do query
  375. user_all = if params[:role_ids] && !params[:role_ids].empty?
  376. User.joins(:roles).where( 'roles.id' => params[:role_ids] ).where('users.id != 1').order('users.created_at DESC').limit( params[:limit] || 20 )
  377. else
  378. User.where('id != 1').order('created_at DESC').limit( params[:limit] || 20 )
  379. end
  380. # build result list
  381. if !params[:full]
  382. users = []
  383. user_all.each { |user|
  384. realname = user.firstname.to_s + ' ' + user.lastname.to_s
  385. if user.email && user.email.to_s != ''
  386. realname = realname + ' <' + user.email.to_s + '>'
  387. end
  388. a = { id: user.id, label: realname, value: realname }
  389. users.push a
  390. }
  391. # return result
  392. render json: users
  393. return
  394. end
  395. user_ids = []
  396. assets = {}
  397. user_all.each { |user|
  398. assets = user.assets(assets)
  399. user_ids.push user.id
  400. }
  401. # return result
  402. render json: {
  403. assets: assets,
  404. user_ids: user_ids.uniq,
  405. }
  406. end
  407. # @path [GET] /users/history/{id}
  408. #
  409. # @tag History
  410. # @tag User
  411. #
  412. # @summary Returns the History records of a User record matching the given identifier.
  413. # @notes The requester has to be in the role 'Admin' or 'Agent' to
  414. # get the History records of a User record.
  415. #
  416. # @parameter id(required) [Integer] The identifier matching the requested User record.
  417. #
  418. # @response_message 200 [History] The History records of the requested User record.
  419. # @response_message 401 Invalid session.
  420. def history
  421. # permission check
  422. if !current_user.permissions?('admin.user') && !current_user.permissions?('ticket.agent')
  423. response_access_deny
  424. return
  425. end
  426. # get user data
  427. user = User.find(params[:id])
  428. # get history of user
  429. history = user.history_get(true)
  430. # return result
  431. render json: history
  432. end
  433. =begin
  434. Resource:
  435. POST /api/v1/users/email_verify
  436. Payload:
  437. {
  438. "token": "SoMeToKeN",
  439. }
  440. Response:
  441. {
  442. :message => 'ok'
  443. }
  444. Test:
  445. curl http://localhost/api/v1/users/email_verify.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"token": "SoMeToKeN"}'
  446. =end
  447. def email_verify
  448. raise Exceptions::UnprocessableEntity, 'No token!' if !params[:token]
  449. user = User.signup_verify_via_token(params[:token], current_user)
  450. raise Exceptions::UnprocessableEntity, 'Invalid token!' if !user
  451. render json: { message: 'ok', user_email: user.email }, status: :ok
  452. end
  453. =begin
  454. Resource:
  455. POST /api/v1/users/email_verify_send
  456. Payload:
  457. {
  458. "email": "some_email@example.com"
  459. }
  460. Response:
  461. {
  462. :message => 'ok'
  463. }
  464. Test:
  465. curl http://localhost/api/v1/users/email_verify_send.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"email": "some_email@example.com"}'
  466. =end
  467. def email_verify_send
  468. raise Exceptions::UnprocessableEntity, 'No email!' if !params[:email]
  469. # check is verify is possible to send
  470. user = User.find_by(email: params[:email].downcase)
  471. raise Exceptions::UnprocessableEntity, 'No such user!' if !user
  472. #if user.verified == true
  473. # render json: { error: 'Already verified!' }, status: :unprocessable_entity
  474. # return
  475. #end
  476. token = Token.create(action: 'Signup', user_id: user.id)
  477. result = User.signup_new_token(user)
  478. if result && result[:token]
  479. user = result[:user]
  480. NotificationFactory::Mailer.notification(
  481. template: 'signup',
  482. user: user,
  483. objects: result
  484. )
  485. # only if system is in develop mode, send token back to browser for browser tests
  486. if Setting.get('developer_mode') == true
  487. render json: { message: 'ok', token: result[:token].name }, status: :ok
  488. return
  489. end
  490. # token sent to user, send ok to browser
  491. render json: { message: 'ok' }, status: :ok
  492. return
  493. end
  494. # unable to generate token
  495. render json: { message: 'failed' }, status: :ok
  496. end
  497. =begin
  498. Resource:
  499. POST /api/v1/users/password_reset
  500. Payload:
  501. {
  502. "username": "some user name"
  503. }
  504. Response:
  505. {
  506. :message => 'ok'
  507. }
  508. Test:
  509. curl http://localhost/api/v1/users/password_reset.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"username": "some_username"}'
  510. =end
  511. def password_reset_send
  512. # check if feature is enabled
  513. raise Exceptions::UnprocessableEntity, 'Feature not enabled!' if !Setting.get('user_lost_password')
  514. result = User.password_reset_new_token(params[:username])
  515. if result && result[:token]
  516. # send mail
  517. user = result[:user]
  518. NotificationFactory::Mailer.notification(
  519. template: 'password_reset',
  520. user: user,
  521. objects: result
  522. )
  523. # only if system is in develop mode, send token back to browser for browser tests
  524. if Setting.get('developer_mode') == true
  525. render json: { message: 'ok', token: result[:token].name }, status: :ok
  526. return
  527. end
  528. # token sent to user, send ok to browser
  529. render json: { message: 'ok' }, status: :ok
  530. return
  531. end
  532. # unable to generate token
  533. render json: { message: 'failed' }, status: :ok
  534. end
  535. =begin
  536. Resource:
  537. POST /api/v1/users/password_reset_verify
  538. Payload:
  539. {
  540. "token": "SoMeToKeN",
  541. "password": "new_password"
  542. }
  543. Response:
  544. {
  545. :message => 'ok'
  546. }
  547. Test:
  548. curl http://localhost/api/v1/users/password_reset_verify.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"token": "SoMeToKeN", "password" "new_password"}'
  549. =end
  550. def password_reset_verify
  551. if params[:password]
  552. # check password policy
  553. result = password_policy(params[:password])
  554. if result != true
  555. render json: { message: 'failed', notice: result }, status: :ok
  556. return
  557. end
  558. # set new password with token
  559. user = User.password_reset_via_token(params[:token], params[:password])
  560. # send mail
  561. if user
  562. NotificationFactory::Mailer.notification(
  563. template: 'password_change',
  564. user: user,
  565. objects: {
  566. user: user,
  567. current_user: current_user,
  568. }
  569. )
  570. end
  571. else
  572. user = User.password_reset_check(params[:token])
  573. end
  574. if user
  575. render json: { message: 'ok', user_login: user.login }, status: :ok
  576. else
  577. render json: { message: 'failed' }, status: :ok
  578. end
  579. end
  580. =begin
  581. Resource:
  582. POST /api/v1/users/password_change
  583. Payload:
  584. {
  585. "password_old": "some_password_old",
  586. "password_new": "some_password_new"
  587. }
  588. Response:
  589. {
  590. :message => 'ok'
  591. }
  592. Test:
  593. curl http://localhost/api/v1/users/password_change.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"password_old": "password_old", "password_new": "password_new"}'
  594. =end
  595. def password_change
  596. # check old password
  597. if !params[:password_old]
  598. render json: { message: 'failed', notice: ['Current password needed!'] }, status: :ok
  599. return
  600. end
  601. user = User.authenticate(current_user.login, params[:password_old])
  602. if !user
  603. render json: { message: 'failed', notice: ['Current password is wrong!'] }, status: :ok
  604. return
  605. end
  606. # set new password
  607. if !params[:password_new]
  608. render json: { message: 'failed', notice: ['Please supply your new password!'] }, status: :ok
  609. return
  610. end
  611. # check password policy
  612. result = password_policy(params[:password_new])
  613. if result != true
  614. render json: { message: 'failed', notice: result }, status: :ok
  615. return
  616. end
  617. user.update_attributes(password: params[:password_new])
  618. NotificationFactory::Mailer.notification(
  619. template: 'password_change',
  620. user: user,
  621. objects: {
  622. user: user,
  623. current_user: current_user,
  624. }
  625. )
  626. render json: { message: 'ok', user_login: user.login }, status: :ok
  627. end
  628. =begin
  629. Resource:
  630. PUT /api/v1/users/preferences.json
  631. Payload:
  632. {
  633. "language": "de",
  634. "notification": true
  635. }
  636. Response:
  637. {
  638. :message => 'ok'
  639. }
  640. Test:
  641. curl http://localhost/api/v1/users/preferences.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"language": "de", "notifications": true}'
  642. =end
  643. def preferences
  644. raise Exceptions::UnprocessableEntity, 'No current user!' if !current_user
  645. if params[:user]
  646. user = User.find(current_user.id)
  647. user.with_lock do
  648. params[:user].each { |key, value|
  649. user.preferences[key.to_sym] = value
  650. }
  651. user.save
  652. end
  653. end
  654. render json: { message: 'ok' }, status: :ok
  655. end
  656. =begin
  657. Resource:
  658. DELETE /api/v1/users/account.json
  659. Payload:
  660. {
  661. "provider": "twitter",
  662. "uid": 581482342942
  663. }
  664. Response:
  665. {
  666. :message => 'ok'
  667. }
  668. Test:
  669. curl http://localhost/api/v1/users/account.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"provider": "twitter", "uid": 581482342942}'
  670. =end
  671. def account_remove
  672. raise Exceptions::UnprocessableEntity, 'No current user!' if !current_user
  673. # provider + uid to remove
  674. raise Exceptions::UnprocessableEntity, 'provider needed!' if !params[:provider]
  675. raise Exceptions::UnprocessableEntity, 'uid needed!' if !params[:uid]
  676. # remove from database
  677. record = Authorization.where(
  678. user_id: current_user.id,
  679. provider: params[:provider],
  680. uid: params[:uid],
  681. )
  682. raise Exceptions::UnprocessableEntity, 'No record found!' if !record.first
  683. record.destroy_all
  684. render json: { message: 'ok' }, status: :ok
  685. end
  686. =begin
  687. Resource:
  688. GET /api/v1/users/image/8d6cca1c6bdc226cf2ba131e264ca2c7
  689. Response:
  690. <IMAGE>
  691. Test:
  692. curl http://localhost/api/v1/users/image/8d6cca1c6bdc226cf2ba131e264ca2c7 -v -u #{login}:#{password}
  693. =end
  694. def image
  695. # cache image
  696. response.headers['Expires'] = 1.year.from_now.httpdate
  697. response.headers['Cache-Control'] = 'cache, store, max-age=31536000, must-revalidate'
  698. response.headers['Pragma'] = 'cache'
  699. file = Avatar.get_by_hash(params[:hash])
  700. if file
  701. send_data(
  702. file.content,
  703. filename: file.filename,
  704. type: file.preferences['Content-Type'] || file.preferences['Mime-Type'],
  705. disposition: 'inline'
  706. )
  707. return
  708. end
  709. # serve default image
  710. image = 'R0lGODdhMAAwAOMAAMzMzJaWlr6+vqqqqqOjo8XFxbe3t7GxsZycnAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAMAAwAAAEcxDISau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru98TwuAA+KQAQqJK8EAgBAgMEqmkzUgBIeSwWGZtR5XhSqAULACCoGCJGwlm1MGQrq9RqgB8fm4ZTUgDBIEcRR9fz6HiImKi4yNjo+QkZKTlJWWkBEAOw=='
  711. send_data(
  712. Base64.decode64(image),
  713. filename: 'image.gif',
  714. type: 'image/gif',
  715. disposition: 'inline'
  716. )
  717. end
  718. =begin
  719. Resource:
  720. POST /api/v1/users/avatar
  721. Payload:
  722. {
  723. "avatar_full": "base64 url",
  724. }
  725. Response:
  726. {
  727. message: 'ok'
  728. }
  729. Test:
  730. curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"avatar": "base64 url"}'
  731. =end
  732. def avatar_new
  733. return if !valid_session_with_user
  734. # get & validate image
  735. file_full = StaticAssets.data_url_attributes(params[:avatar_full])
  736. file_resize = StaticAssets.data_url_attributes(params[:avatar_resize])
  737. avatar = Avatar.add(
  738. object: 'User',
  739. o_id: current_user.id,
  740. full: {
  741. content: file_full[:content],
  742. mime_type: file_full[:mime_type],
  743. },
  744. resize: {
  745. content: file_resize[:content],
  746. mime_type: file_resize[:mime_type],
  747. },
  748. source: 'upload ' + Time.zone.now.to_s,
  749. deletable: true,
  750. )
  751. # update user link
  752. user = User.find(current_user.id)
  753. user.update_attributes(image: avatar.store_hash)
  754. render json: { avatar: avatar }, status: :ok
  755. end
  756. def avatar_set_default
  757. return if !valid_session_with_user
  758. # get & validate image
  759. raise Exceptions::UnprocessableEntity, 'No id of avatar!' if !params[:id]
  760. # set as default
  761. avatar = Avatar.set_default('User', current_user.id, params[:id])
  762. # update user link
  763. user = User.find(current_user.id)
  764. user.update_attributes(image: avatar.store_hash)
  765. render json: {}, status: :ok
  766. end
  767. def avatar_destroy
  768. return if !valid_session_with_user
  769. # get & validate image
  770. raise Exceptions::UnprocessableEntity, 'No id of avatar!' if !params[:id]
  771. # remove avatar
  772. Avatar.remove_one('User', current_user.id, params[:id])
  773. # update user link
  774. avatar = Avatar.get_default('User', current_user.id)
  775. user = User.find(current_user.id)
  776. user.update_attributes(image: avatar.store_hash)
  777. render json: {}, status: :ok
  778. end
  779. def avatar_list
  780. return if !valid_session_with_user
  781. # list of avatars
  782. result = Avatar.list('User', current_user.id)
  783. render json: { avatars: result }, status: :ok
  784. end
  785. private
  786. def password_policy(password)
  787. if Setting.get('password_min_size').to_i > password.length
  788. return ["Can\'t update password, it must be at least %s characters long!", Setting.get('password_min_size')]
  789. end
  790. if Setting.get('password_need_digit').to_i == 1 && password !~ /\d/
  791. return ["Can't update password, it must contain at least 1 digit!"]
  792. end
  793. if Setting.get('password_min_2_lower_2_upper_characters').to_i == 1 && ( password !~ /[A-Z].*[A-Z]/ || password !~ /[a-z].*[a-z]/ )
  794. return ["Can't update password, it must contain at least 2 lowercase and 2 uppercase characters!"]
  795. end
  796. true
  797. end
  798. def permission_check_by_permission(params)
  799. return true if current_user.permissions?('admin.user')
  800. if !current_user.permissions?('admin.user') && params[:role_ids]
  801. if params[:role_ids].class != Array
  802. params[:role_ids] = [params[:role_ids]]
  803. end
  804. params[:role_ids].each { |role_id|
  805. role_local = Role.lookup(id: role_id)
  806. if !role_local
  807. logger.info "Invalid role_ids for current_user_id: #{current_user.id} role_ids #{role_id}"
  808. raise Exceptions::NotAuthorized, 'Invalid role_ids!'
  809. end
  810. role_name = role_local.name
  811. # TODO: check role permissions
  812. next if role_name != 'Admin' && role_name != 'Agent'
  813. logger.info "This role assignment is only allowed by admin! current_user_id: #{current_user.id} assigned to #{role_name}"
  814. raise Exceptions::NotAuthorized, 'This role assignment is only allowed by admin!'
  815. }
  816. end
  817. if !current_user.permissions?('admin.user') && params[:group_ids]
  818. if params[:group_ids].class != Array
  819. params[:group_ids] = [params[:group_ids]]
  820. end
  821. if !params[:group_ids].empty?
  822. logger.info "Group relation is only allowed by admin! current_user_id: #{current_user.id} group_ids #{params[:group_ids].inspect}"
  823. raise Exceptions::NotAuthorized, 'Group relation is only allowed by admin!'
  824. end
  825. end
  826. return true if current_user.permissions?('ticket.agent')
  827. response_access_deny
  828. false
  829. end
  830. def permission_check_local
  831. return true if current_user.permissions?('admin.user')
  832. return true if current_user.permissions?('ticket.agent')
  833. # allow to update any by him self
  834. # TODO check certain attributes like roles_ids and group_ids
  835. return true if params[:id].to_i == current_user.id
  836. raise Exceptions::NotAuthorized
  837. end
  838. end