users_controller.rb 29 KB

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