2022-01-01 13:38:12 +00:00
|
|
|
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
|
2013-06-12 15:59:58 +00:00
|
|
|
|
2019-10-15 10:15:58 +00:00
|
|
|
class Token < ApplicationModel
|
2020-08-14 11:12:41 +00:00
|
|
|
include CanBeAuthorized
|
|
|
|
|
2015-08-21 13:33:06 +00:00
|
|
|
before_create :generate_token
|
2019-07-04 11:16:55 +00:00
|
|
|
belongs_to :user, optional: true
|
2016-08-12 16:39:09 +00:00
|
|
|
store :preferences
|
2012-04-23 06:55:16 +00:00
|
|
|
|
2015-08-21 13:33:06 +00:00
|
|
|
=begin
|
|
|
|
|
|
|
|
create new token
|
|
|
|
|
2016-06-01 14:58:11 +00:00
|
|
|
token = Token.create(action: 'PasswordReset', user_id: user.id)
|
2015-08-21 13:33:06 +00:00
|
|
|
|
|
|
|
returns
|
|
|
|
|
|
|
|
the token
|
|
|
|
|
|
|
|
create new persistent token
|
|
|
|
|
|
|
|
token = Token.create(
|
2016-08-12 16:39:09 +00:00
|
|
|
action: 'api',
|
2015-08-21 13:33:06 +00:00
|
|
|
persistent: true,
|
|
|
|
user_id: user.id,
|
2016-08-12 16:39:09 +00:00
|
|
|
preferences: {
|
|
|
|
permission: {
|
|
|
|
'user_preferences.calendar' => true,
|
|
|
|
}
|
|
|
|
}
|
2015-08-21 13:33:06 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
in case if you use it via an controller, e. g. you can verify via "curl -H "Authorization: Token token=33562a00d7eda2a7c2fb639b91c6bcb8422067b6" http://...
|
|
|
|
|
|
|
|
returns
|
|
|
|
|
|
|
|
the token
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
=begin
|
|
|
|
|
|
|
|
check token
|
|
|
|
|
2016-08-30 14:26:27 +00:00
|
|
|
user = Token.check(action: 'PasswordReset', name: '123abc12qweads')
|
2015-08-21 13:33:06 +00:00
|
|
|
|
2016-08-12 16:39:09 +00:00
|
|
|
check api token with permissions
|
|
|
|
|
2016-08-30 14:26:27 +00:00
|
|
|
user = Token.check(action: 'api', name: '123abc12qweads', permission: 'admin.session')
|
2016-08-12 16:39:09 +00:00
|
|
|
|
2017-04-11 06:33:08 +00:00
|
|
|
user = Token.check(action: 'api', name: '123abc12qweads', permission: ['admin.session', 'ticket.agent'])
|
|
|
|
|
2015-08-21 13:33:06 +00:00
|
|
|
returns
|
|
|
|
|
|
|
|
user for who this token was created
|
|
|
|
|
|
|
|
=end
|
2012-04-23 06:55:16 +00:00
|
|
|
|
2016-06-01 14:58:11 +00:00
|
|
|
def self.check(data)
|
2012-04-23 06:55:16 +00:00
|
|
|
|
|
|
|
# fetch token
|
2016-06-01 14:58:11 +00:00
|
|
|
token = Token.find_by(action: data[:action], name: data[:name])
|
2012-04-23 06:55:16 +00:00
|
|
|
return if !token
|
2013-06-12 15:59:58 +00:00
|
|
|
|
2012-04-23 06:55:16 +00:00
|
|
|
# check if token is still valid
|
2015-02-22 18:10:54 +00:00
|
|
|
if !token.persistent &&
|
2015-05-01 12:27:57 +00:00
|
|
|
token.created_at < 1.day.ago
|
2013-01-03 12:00:55 +00:00
|
|
|
|
2012-04-23 06:55:16 +00:00
|
|
|
# delete token
|
|
|
|
token.delete
|
|
|
|
token.save
|
|
|
|
return
|
|
|
|
end
|
2013-01-03 12:00:55 +00:00
|
|
|
|
2016-07-28 12:43:31 +00:00
|
|
|
user = token.user
|
|
|
|
|
2016-08-30 14:26:27 +00:00
|
|
|
# persistent token not valid if user is inactive
|
2020-09-30 09:07:01 +00:00
|
|
|
return if !data[:inactive_user] && token.persistent && user.active == false
|
2016-08-12 16:39:09 +00:00
|
|
|
|
|
|
|
# add permission check
|
2020-09-30 09:07:01 +00:00
|
|
|
return if data[:permission] && !token.permissions?(data[:permission])
|
2016-07-28 12:43:31 +00:00
|
|
|
|
2015-06-23 12:27:17 +00:00
|
|
|
# return token user
|
2016-07-28 12:43:31 +00:00
|
|
|
user
|
2012-04-23 06:55:16 +00:00
|
|
|
end
|
|
|
|
|
2015-08-24 10:09:04 +00:00
|
|
|
=begin
|
|
|
|
|
|
|
|
cleanup old token
|
|
|
|
|
|
|
|
Token.cleanup
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.cleanup
|
2022-01-03 09:47:32 +00:00
|
|
|
Token.where('persistent IS ? AND created_at < ?', nil, 30.days.ago).delete_all
|
2015-08-24 10:09:04 +00:00
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2020-08-14 11:12:41 +00:00
|
|
|
def permissions
|
|
|
|
Permission.where(
|
|
|
|
name: Array(preferences[:permission]),
|
|
|
|
active: true,
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def permissions?(names)
|
2020-09-14 06:34:42 +00:00
|
|
|
return false if !effective_user.permissions?(names)
|
2020-03-19 09:39:51 +00:00
|
|
|
|
2020-08-14 11:12:41 +00:00
|
|
|
super(names)
|
2020-03-19 09:39:51 +00:00
|
|
|
end
|
|
|
|
|
2020-09-14 06:34:42 +00:00
|
|
|
# allows to evaluate token permissions in context of given user instead of owner
|
|
|
|
# @param [User] user to use as context for the given block
|
|
|
|
# @param block to evaluate in given context
|
|
|
|
def with_context(user:, &block)
|
|
|
|
@effective_user = user
|
|
|
|
|
2020-11-24 16:20:57 +00:00
|
|
|
instance_eval(&block) if block
|
2020-09-14 06:34:42 +00:00
|
|
|
ensure
|
|
|
|
@effective_user = nil
|
|
|
|
end
|
|
|
|
|
2012-04-23 06:55:16 +00:00
|
|
|
private
|
2015-05-01 12:31:46 +00:00
|
|
|
|
2013-06-12 15:59:58 +00:00
|
|
|
def generate_token
|
2015-05-05 10:32:25 +00:00
|
|
|
loop do
|
2016-07-28 10:09:32 +00:00
|
|
|
self.name = SecureRandom.urlsafe_base64(48)
|
2016-06-01 14:58:11 +00:00
|
|
|
break if !Token.exists?(name: name)
|
2015-05-05 10:32:25 +00:00
|
|
|
end
|
2017-06-16 22:53:20 +00:00
|
|
|
true
|
2013-06-12 15:59:58 +00:00
|
|
|
end
|
2020-09-14 06:34:42 +00:00
|
|
|
|
|
|
|
# token owner or user set by #with_context
|
|
|
|
def effective_user
|
|
|
|
@effective_user || user
|
|
|
|
end
|
2013-06-12 15:59:58 +00:00
|
|
|
end
|