users_controller.rb 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057
  1. # Copyright (C) 2012-2016 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).order(id: 'ASC').offset(offset).limit(per_page)
  26. else
  27. User.all.order(id: 'ASC').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.empty?
  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.empty?
  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/me
  265. #
  266. # @summary Returns the User record of current user.
  267. # @notes The requestor need to have a valid authentication.
  268. #
  269. # @parameter full [Bool] If set a Asset structure with all connected Assets gets returned.
  270. #
  271. # @response_message 200 [User] User record matching the requested identifier.
  272. # @response_message 401 Invalid session.
  273. def me
  274. if params[:expand]
  275. user = current_user.attributes_with_relation_names
  276. render json: user, status: :ok
  277. return
  278. end
  279. if params[:full]
  280. full = User.full(current_user.id)
  281. render json: full
  282. return
  283. end
  284. user = current_user.attributes_with_associations
  285. user.delete('password')
  286. render json: user
  287. end
  288. # @path [GET] /users/search
  289. #
  290. # @tag Search
  291. # @tag User
  292. #
  293. # @summary Searches the User matching the given expression(s).
  294. # @notes TODO: It's possible to use the SOLR search syntax.
  295. # The requester has to be in the role 'Admin' or 'Agent' to
  296. # be able to search for User records.
  297. #
  298. # @parameter query [String] The search query.
  299. # @parameter limit [Integer] The limit of search results.
  300. # @parameter role_ids(multi) [Array<String>] A list of Role identifiers to which the Users have to be allocated to.
  301. # @parameter full [Boolean] Defines if the result should be
  302. # true: { user_ids => [1,2,...], assets => {...} }
  303. # or false: [{:id => user.id, :label => "firstname lastname <email>", :value => "firstname lastname <email>"},...].
  304. #
  305. # @response_message 200 [Array<User>] A list of User records matching the search term.
  306. # @response_message 401 Invalid session.
  307. def search
  308. if !current_user.permissions?('ticket.agent') && !current_user.permissions?('admin.user')
  309. response_access_deny
  310. return
  311. end
  312. # set limit for pagination if needed
  313. if params[:page] && params[:per_page]
  314. params[:limit] = params[:page].to_i * params[:per_page].to_i
  315. end
  316. if params[:limit] && params[:limit].to_i > 500
  317. params[:limit].to_i = 500
  318. end
  319. query_params = {
  320. query: params[:query],
  321. limit: params[:limit],
  322. current_user: current_user,
  323. }
  324. if params[:role_ids] && !params[:role_ids].empty?
  325. query_params[:role_ids] = params[:role_ids]
  326. end
  327. # do query
  328. user_all = User.search(query_params)
  329. # do pagination if needed
  330. if params[:page] && params[:per_page]
  331. offset = (params[:page].to_i - 1) * params[:per_page].to_i
  332. user_all = user_all.slice(offset, params[:per_page].to_i) || []
  333. end
  334. if params[:expand]
  335. list = []
  336. user_all.each { |user|
  337. list.push user.attributes_with_relation_names
  338. }
  339. render json: list, status: :ok
  340. return
  341. end
  342. # build result list
  343. if params[:label]
  344. users = []
  345. user_all.each { |user|
  346. realname = user.firstname.to_s + ' ' + user.lastname.to_s
  347. if user.email && user.email.to_s != ''
  348. realname = realname + ' <' + user.email.to_s + '>'
  349. end
  350. a = { id: user.id, label: realname, value: realname }
  351. users.push a
  352. }
  353. # return result
  354. render json: users
  355. return
  356. end
  357. if params[:full]
  358. user_ids = []
  359. assets = {}
  360. user_all.each { |user|
  361. assets = user.assets(assets)
  362. user_ids.push user.id
  363. }
  364. # return result
  365. render json: {
  366. assets: assets,
  367. user_ids: user_ids.uniq,
  368. }
  369. return
  370. end
  371. list = []
  372. user_all.each { |user|
  373. list.push user.attributes
  374. }
  375. render json: list, status: :ok
  376. end
  377. # @path [GET] /users/recent
  378. #
  379. # @tag Search
  380. # @tag User
  381. #
  382. # @summary Recent creates Users.
  383. # @notes Recent creates Users.
  384. #
  385. # @parameter limit [Integer] The limit of search results.
  386. # @parameter role_ids(multi) [Array<String>] A list of Role identifiers to which the Users have to be allocated to.
  387. # @parameter full [Boolean] Defines if the result should be
  388. # true: { user_ids => [1,2,...], assets => {...} }
  389. # or false: [{:id => user.id, :label => "firstname lastname <email>", :value => "firstname lastname <email>"},...].
  390. #
  391. # @response_message 200 [Array<User>] A list of User records matching the search term.
  392. # @response_message 401 Invalid session.
  393. def recent
  394. if !current_user.permissions?('admin.user')
  395. response_access_deny
  396. return
  397. end
  398. # do query
  399. user_all = if params[:role_ids] && !params[:role_ids].empty?
  400. User.joins(:roles).where( 'roles.id' => params[:role_ids] ).where('users.id != 1').order('users.created_at DESC').limit( params[:limit] || 20 )
  401. else
  402. User.where('id != 1').order('created_at DESC').limit( params[:limit] || 20 )
  403. end
  404. # build result list
  405. if !params[:full]
  406. users = []
  407. user_all.each { |user|
  408. realname = user.firstname.to_s + ' ' + user.lastname.to_s
  409. if user.email && user.email.to_s != ''
  410. realname = realname + ' <' + user.email.to_s + '>'
  411. end
  412. a = { id: user.id, label: realname, value: realname }
  413. users.push a
  414. }
  415. # return result
  416. render json: users
  417. return
  418. end
  419. user_ids = []
  420. assets = {}
  421. user_all.each { |user|
  422. assets = user.assets(assets)
  423. user_ids.push user.id
  424. }
  425. # return result
  426. render json: {
  427. assets: assets,
  428. user_ids: user_ids.uniq,
  429. }
  430. end
  431. # @path [GET] /users/history/{id}
  432. #
  433. # @tag History
  434. # @tag User
  435. #
  436. # @summary Returns the History records of a User record matching the given identifier.
  437. # @notes The requester has to be in the role 'Admin' or 'Agent' to
  438. # get the History records of a User record.
  439. #
  440. # @parameter id(required) [Integer] The identifier matching the requested User record.
  441. #
  442. # @response_message 200 [History] The History records of the requested User record.
  443. # @response_message 401 Invalid session.
  444. def history
  445. # permission check
  446. if !current_user.permissions?('admin.user') && !current_user.permissions?('ticket.agent')
  447. response_access_deny
  448. return
  449. end
  450. # get user data
  451. user = User.find(params[:id])
  452. # get history of user
  453. history = user.history_get(true)
  454. # return result
  455. render json: history
  456. end
  457. =begin
  458. Resource:
  459. POST /api/v1/users/email_verify
  460. Payload:
  461. {
  462. "token": "SoMeToKeN",
  463. }
  464. Response:
  465. {
  466. :message => 'ok'
  467. }
  468. Test:
  469. curl http://localhost/api/v1/users/email_verify.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"token": "SoMeToKeN"}'
  470. =end
  471. def email_verify
  472. raise Exceptions::UnprocessableEntity, 'No token!' if !params[:token]
  473. user = User.signup_verify_via_token(params[:token], current_user)
  474. raise Exceptions::UnprocessableEntity, 'Invalid token!' if !user
  475. render json: { message: 'ok', user_email: user.email }, status: :ok
  476. end
  477. =begin
  478. Resource:
  479. POST /api/v1/users/email_verify_send
  480. Payload:
  481. {
  482. "email": "some_email@example.com"
  483. }
  484. Response:
  485. {
  486. :message => 'ok'
  487. }
  488. Test:
  489. 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"}'
  490. =end
  491. def email_verify_send
  492. raise Exceptions::UnprocessableEntity, 'No email!' if !params[:email]
  493. # check is verify is possible to send
  494. user = User.find_by(email: params[:email].downcase)
  495. raise Exceptions::UnprocessableEntity, 'No such user!' if !user
  496. #if user.verified == true
  497. # render json: { error: 'Already verified!' }, status: :unprocessable_entity
  498. # return
  499. #end
  500. token = Token.create(action: 'Signup', user_id: user.id)
  501. result = User.signup_new_token(user)
  502. if result && result[:token]
  503. user = result[:user]
  504. NotificationFactory::Mailer.notification(
  505. template: 'signup',
  506. user: user,
  507. objects: result
  508. )
  509. # only if system is in develop mode, send token back to browser for browser tests
  510. if Setting.get('developer_mode') == true
  511. render json: { message: 'ok', token: result[:token].name }, status: :ok
  512. return
  513. end
  514. # token sent to user, send ok to browser
  515. render json: { message: 'ok' }, status: :ok
  516. return
  517. end
  518. # unable to generate token
  519. render json: { message: 'failed' }, status: :ok
  520. end
  521. =begin
  522. Resource:
  523. POST /api/v1/users/password_reset
  524. Payload:
  525. {
  526. "username": "some user name"
  527. }
  528. Response:
  529. {
  530. :message => 'ok'
  531. }
  532. Test:
  533. curl http://localhost/api/v1/users/password_reset.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"username": "some_username"}'
  534. =end
  535. def password_reset_send
  536. # check if feature is enabled
  537. raise Exceptions::UnprocessableEntity, 'Feature not enabled!' if !Setting.get('user_lost_password')
  538. result = User.password_reset_new_token(params[:username])
  539. if result && result[:token]
  540. # send mail
  541. user = result[:user]
  542. NotificationFactory::Mailer.notification(
  543. template: 'password_reset',
  544. user: user,
  545. objects: result
  546. )
  547. # only if system is in develop mode, send token back to browser for browser tests
  548. if Setting.get('developer_mode') == true
  549. render json: { message: 'ok', token: result[:token].name }, status: :ok
  550. return
  551. end
  552. # token sent to user, send ok to browser
  553. render json: { message: 'ok' }, status: :ok
  554. return
  555. end
  556. # unable to generate token
  557. render json: { message: 'failed' }, status: :ok
  558. end
  559. =begin
  560. Resource:
  561. POST /api/v1/users/password_reset_verify
  562. Payload:
  563. {
  564. "token": "SoMeToKeN",
  565. "password": "new_password"
  566. }
  567. Response:
  568. {
  569. :message => 'ok'
  570. }
  571. Test:
  572. 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"}'
  573. =end
  574. def password_reset_verify
  575. if params[:password]
  576. # check password policy
  577. result = password_policy(params[:password])
  578. if result != true
  579. render json: { message: 'failed', notice: result }, status: :ok
  580. return
  581. end
  582. # set new password with token
  583. user = User.password_reset_via_token(params[:token], params[:password])
  584. # send mail
  585. if user
  586. NotificationFactory::Mailer.notification(
  587. template: 'password_change',
  588. user: user,
  589. objects: {
  590. user: user,
  591. current_user: current_user,
  592. }
  593. )
  594. end
  595. else
  596. user = User.password_reset_check(params[:token])
  597. end
  598. if user
  599. render json: { message: 'ok', user_login: user.login }, status: :ok
  600. else
  601. render json: { message: 'failed' }, status: :ok
  602. end
  603. end
  604. =begin
  605. Resource:
  606. POST /api/v1/users/password_change
  607. Payload:
  608. {
  609. "password_old": "some_password_old",
  610. "password_new": "some_password_new"
  611. }
  612. Response:
  613. {
  614. :message => 'ok'
  615. }
  616. Test:
  617. 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"}'
  618. =end
  619. def password_change
  620. # check old password
  621. if !params[:password_old]
  622. render json: { message: 'failed', notice: ['Current password needed!'] }, status: :ok
  623. return
  624. end
  625. user = User.authenticate(current_user.login, params[:password_old])
  626. if !user
  627. render json: { message: 'failed', notice: ['Current password is wrong!'] }, status: :ok
  628. return
  629. end
  630. # set new password
  631. if !params[:password_new]
  632. render json: { message: 'failed', notice: ['Please supply your new password!'] }, status: :ok
  633. return
  634. end
  635. # check password policy
  636. result = password_policy(params[:password_new])
  637. if result != true
  638. render json: { message: 'failed', notice: result }, status: :ok
  639. return
  640. end
  641. user.update_attributes(password: params[:password_new])
  642. NotificationFactory::Mailer.notification(
  643. template: 'password_change',
  644. user: user,
  645. objects: {
  646. user: user,
  647. current_user: current_user,
  648. }
  649. )
  650. render json: { message: 'ok', user_login: user.login }, status: :ok
  651. end
  652. =begin
  653. Resource:
  654. PUT /api/v1/users/preferences.json
  655. Payload:
  656. {
  657. "language": "de",
  658. "notification": true
  659. }
  660. Response:
  661. {
  662. :message => 'ok'
  663. }
  664. Test:
  665. curl http://localhost/api/v1/users/preferences.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"language": "de", "notifications": true}'
  666. =end
  667. def preferences
  668. raise Exceptions::UnprocessableEntity, 'No current user!' if !current_user
  669. if params[:user]
  670. user = User.find(current_user.id)
  671. user.with_lock do
  672. params[:user].each { |key, value|
  673. user.preferences[key.to_sym] = value
  674. }
  675. user.save
  676. end
  677. end
  678. render json: { message: 'ok' }, status: :ok
  679. end
  680. =begin
  681. Resource:
  682. DELETE /api/v1/users/account.json
  683. Payload:
  684. {
  685. "provider": "twitter",
  686. "uid": 581482342942
  687. }
  688. Response:
  689. {
  690. :message => 'ok'
  691. }
  692. Test:
  693. curl http://localhost/api/v1/users/account.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"provider": "twitter", "uid": 581482342942}'
  694. =end
  695. def account_remove
  696. raise Exceptions::UnprocessableEntity, 'No current user!' if !current_user
  697. # provider + uid to remove
  698. raise Exceptions::UnprocessableEntity, 'provider needed!' if !params[:provider]
  699. raise Exceptions::UnprocessableEntity, 'uid needed!' if !params[:uid]
  700. # remove from database
  701. record = Authorization.where(
  702. user_id: current_user.id,
  703. provider: params[:provider],
  704. uid: params[:uid],
  705. )
  706. raise Exceptions::UnprocessableEntity, 'No record found!' if !record.first
  707. record.destroy_all
  708. render json: { message: 'ok' }, status: :ok
  709. end
  710. =begin
  711. Resource:
  712. GET /api/v1/users/image/8d6cca1c6bdc226cf2ba131e264ca2c7
  713. Response:
  714. <IMAGE>
  715. Test:
  716. curl http://localhost/api/v1/users/image/8d6cca1c6bdc226cf2ba131e264ca2c7 -v -u #{login}:#{password}
  717. =end
  718. def image
  719. # cache image
  720. response.headers['Expires'] = 1.year.from_now.httpdate
  721. response.headers['Cache-Control'] = 'cache, store, max-age=31536000, must-revalidate'
  722. response.headers['Pragma'] = 'cache'
  723. file = Avatar.get_by_hash(params[:hash])
  724. if file
  725. send_data(
  726. file.content,
  727. filename: file.filename,
  728. type: file.preferences['Content-Type'] || file.preferences['Mime-Type'],
  729. disposition: 'inline'
  730. )
  731. return
  732. end
  733. # serve default image
  734. image = 'R0lGODdhMAAwAOMAAMzMzJaWlr6+vqqqqqOjo8XFxbe3t7GxsZycnAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAMAAwAAAEcxDISau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru98TwuAA+KQAQqJK8EAgBAgMEqmkzUgBIeSwWGZtR5XhSqAULACCoGCJGwlm1MGQrq9RqgB8fm4ZTUgDBIEcRR9fz6HiImKi4yNjo+QkZKTlJWWkBEAOw=='
  735. send_data(
  736. Base64.decode64(image),
  737. filename: 'image.gif',
  738. type: 'image/gif',
  739. disposition: 'inline'
  740. )
  741. end
  742. =begin
  743. Resource:
  744. POST /api/v1/users/avatar
  745. Payload:
  746. {
  747. "avatar_full": "base64 url",
  748. }
  749. Response:
  750. {
  751. message: 'ok'
  752. }
  753. Test:
  754. curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"avatar": "base64 url"}'
  755. =end
  756. def avatar_new
  757. return if !valid_session_with_user
  758. # get & validate image
  759. file_full = StaticAssets.data_url_attributes(params[:avatar_full])
  760. file_resize = StaticAssets.data_url_attributes(params[:avatar_resize])
  761. avatar = Avatar.add(
  762. object: 'User',
  763. o_id: current_user.id,
  764. full: {
  765. content: file_full[:content],
  766. mime_type: file_full[:mime_type],
  767. },
  768. resize: {
  769. content: file_resize[:content],
  770. mime_type: file_resize[:mime_type],
  771. },
  772. source: 'upload ' + Time.zone.now.to_s,
  773. deletable: true,
  774. )
  775. # update user link
  776. user = User.find(current_user.id)
  777. user.update_attributes(image: avatar.store_hash)
  778. render json: { avatar: avatar }, status: :ok
  779. end
  780. def avatar_set_default
  781. return if !valid_session_with_user
  782. # get & validate image
  783. raise Exceptions::UnprocessableEntity, 'No id of avatar!' if !params[:id]
  784. # set as default
  785. avatar = Avatar.set_default('User', current_user.id, params[:id])
  786. # update user link
  787. user = User.find(current_user.id)
  788. user.update_attributes(image: avatar.store_hash)
  789. render json: {}, status: :ok
  790. end
  791. def avatar_destroy
  792. return if !valid_session_with_user
  793. # get & validate image
  794. raise Exceptions::UnprocessableEntity, 'No id of avatar!' if !params[:id]
  795. # remove avatar
  796. Avatar.remove_one('User', current_user.id, params[:id])
  797. # update user link
  798. avatar = Avatar.get_default('User', current_user.id)
  799. user = User.find(current_user.id)
  800. user.update_attributes(image: avatar.store_hash)
  801. render json: {}, status: :ok
  802. end
  803. def avatar_list
  804. return if !valid_session_with_user
  805. # list of avatars
  806. result = Avatar.list('User', current_user.id)
  807. render json: { avatars: result }, status: :ok
  808. end
  809. private
  810. def password_policy(password)
  811. if Setting.get('password_min_size').to_i > password.length
  812. return ["Can\'t update password, it must be at least %s characters long!", Setting.get('password_min_size')]
  813. end
  814. if Setting.get('password_need_digit').to_i == 1 && password !~ /\d/
  815. return ["Can't update password, it must contain at least 1 digit!"]
  816. end
  817. if Setting.get('password_min_2_lower_2_upper_characters').to_i == 1 && ( password !~ /[A-Z].*[A-Z]/ || password !~ /[a-z].*[a-z]/ )
  818. return ["Can't update password, it must contain at least 2 lowercase and 2 uppercase characters!"]
  819. end
  820. true
  821. end
  822. def permission_check_by_permission(params)
  823. return true if current_user.permissions?('admin.user')
  824. if !current_user.permissions?('admin.user') && params[:role_ids]
  825. if params[:role_ids].class != Array
  826. params[:role_ids] = [params[:role_ids]]
  827. end
  828. params[:role_ids].each { |role_id|
  829. role_local = Role.lookup(id: role_id)
  830. if !role_local
  831. logger.info "Invalid role_ids for current_user_id: #{current_user.id} role_ids #{role_id}"
  832. raise Exceptions::NotAuthorized, 'Invalid role_ids!'
  833. end
  834. role_name = role_local.name
  835. # TODO: check role permissions
  836. next if role_name != 'Admin' && role_name != 'Agent'
  837. logger.info "This role assignment is only allowed by admin! current_user_id: #{current_user.id} assigned to #{role_name}"
  838. raise Exceptions::NotAuthorized, 'This role assignment is only allowed by admin!'
  839. }
  840. end
  841. if !current_user.permissions?('admin.user') && params[:group_ids]
  842. if params[:group_ids].class != Array
  843. params[:group_ids] = [params[:group_ids]]
  844. end
  845. if !params[:group_ids].empty?
  846. logger.info "Group relation is only allowed by admin! current_user_id: #{current_user.id} group_ids #{params[:group_ids].inspect}"
  847. raise Exceptions::NotAuthorized, 'Group relation is only allowed by admin!'
  848. end
  849. end
  850. return true if current_user.permissions?('ticket.agent')
  851. response_access_deny
  852. false
  853. end
  854. def permission_check_local
  855. return true if current_user.permissions?('admin.user')
  856. return true if current_user.permissions?('ticket.agent')
  857. # allow to update any by him self
  858. # TODO check certain attributes like roles_ids and group_ids
  859. return true if params[:id].to_i == current_user.id
  860. raise Exceptions::NotAuthorized
  861. end
  862. end