Merge branch 'develop' of github.com:martini/zammad into develop

Conflicts:
	app/assets/javascripts/app/controllers/layout_ref.js.coffee
This commit is contained in:
Martin Edenhofer 2015-06-24 13:36:17 +02:00
commit afe4181247
11 changed files with 263 additions and 89 deletions

View file

@ -1289,6 +1289,7 @@ class slaRef extends App.ControllerContent
'click .js-activateColumn': 'activateColumn' 'click .js-activateColumn': 'activateColumn'
'click .js-activateRow': 'activateRow' 'click .js-activateRow': 'activateRow'
'click [data-type=new]': 'createNew' 'click [data-type=new]': 'createNew'
'click .js-toggle': 'toggleSla'
constructor: -> constructor: ->
super super
@ -1297,6 +1298,13 @@ class slaRef extends App.ControllerContent
render: -> render: ->
@html App.view('layout_ref/sla')() @html App.view('layout_ref/sla')()
toggleSla: (e) =>
sla = $(e.currentTarget).closest('.sla')
isInactive = sla.hasClass('is-inactive')
sla.toggleClass('is-inactive')
isInactive = !isInactive
sla.find('.js-toggle').text(if isInactive then 'Enable' else 'Disable')
activateColumn: (event) => activateColumn: (event) =>
checkbox = @$(event.currentTarget) checkbox = @$(event.currentTarget)
columnName = checkbox.attr('data-target') columnName = checkbox.attr('data-target')

View file

@ -76,15 +76,93 @@
</div> </div>
</div> </div>
<div class="table-overview"> <div class="sla">
<p> <div class="sla-filters">
<strong>Service-Level-Agreements</strong>, abgekürzt <b>SLAs</b>, unterstützen Sie gegenüber Kunden gewisse zeitliche Reaktionen einzuhalten. Somit können Sie z. B. sagen Kunden sollen immer nach spätestens 8 Stunden eine Reaktion von Ihnen bekommen. Falls es zu einer drohenden Unterschreitung oder einer Unterschreitung kommt, weißt Zammad Sie auf solche Ereignisse hin. <h3>Filters</h3>
</p> Where <b>Organization</b> equals to <b>Deutsche Bank</b>.<br>
<p> Where <b>Priority</b> is <b>high</b>.
Es können <strong>Reaktionszeit</strong> (Zeit zwischen Erstellung eines Tickets und erster Reaktion eines Agenten), <strong>Aktualisierungszeit</strong> (Zeit zwischen Nachfrage eines Kunden und Reaktion eines Agenten) und <strong>Lösungszeit</strong> (Zeit zwischen Erstellung und schließen eines Tickets) definiert werden. </div>
</p> <div class="arrow">
<p> <svg class="icon"><use xlink:href="#icon-arrow-right" /></svg>
Drohenden Unterschreitungen oder Unterschreitungen werden in einer eigenen Ansicht in den Übersichten angezeigt. Zudem können <strong>E-Mail Benachrichtigungen</strong> konfiguriert werden. </div>
</p> <div class="sla-times">
<h3>Repsonse Times</h3>
<div class="response-times">
<div class="response-times-entry">
<div class="response-time">00:30 Stunden</div>
<div class="response-name">
<svg class="icon icon-reply"><use xlink:href="#icon-reply" /></svg>
First Response Time
</div>
</div>
<div class="response-times-entry">
<div class="response-time">01:00 Stunden</div>
<div class="response-name">
<svg class="icon icon-reply-all"><use xlink:href="#icon-reply-all" /></svg>
Update Time
</div>
</div>
<div class="response-times-entry">
<div class="response-time">48:00 Stunden</div>
<div class="response-name">
<svg class="icon icon-checkmark"><use xlink:href="#icon-checkmark" /></svg>
Solution Time
</div>
</div>
</div>
</div>
<div class="sla-businessHours">
<h3>Business Hours <span class="subtitle">in European Central Time</span></h3>
Mo-Tu 7am - 5pm, Fr 7am - 1pm
</div>
<div class="sla-controls">
<div class="sla-toggle btn js-toggle">Disable</div>
<div class="sla-edit btn js-edit">Edit</div>
</div>
</div>
<div class="sla is-inactive">
<div class="sla-filters">
<h3>Filters</h3>
Where <b>Organization</b> equals to <b>Deutsche Bank</b>.<br>
Where <b>Priority</b> is <b>high</b>.
</div>
<div class="arrow">
<svg class="icon"><use xlink:href="#icon-arrow-right" /></svg>
</div>
<div class="sla-times">
<h3>Repsonse Times</h3>
<div class="response-times">
<div class="response-times-entry">
<div class="response-time">00:30 Stunden</div>
<div class="response-name">
<svg class="icon icon-reply"><use xlink:href="#icon-reply" /></svg>
First Response Time
</div>
</div>
<div class="response-times-entry">
<div class="response-time">01:00 Stunden</div>
<div class="response-name">
<svg class="icon icon-reply-all"><use xlink:href="#icon-reply-all" /></svg>
Update Time
</div>
</div>
<div class="response-times-entry">
<div class="response-time">48:00 Stunden</div>
<div class="response-name">
<svg class="icon icon-checkmark"><use xlink:href="#icon-checkmark" /></svg>
Solution Time
</div>
</div>
</div>
</div>
<div class="sla-businessHours">
<h3>Business Hours <span class="subtitle">in European Central Time</span></h3>
Mo-Tu 7am - 5pm, Fr 7am - 1pm
</div>
<div class="sla-controls">
<div class="sla-toggle btn js-toggle">Enable</div>
<div class="sla-edit btn js-edit">Edit</div>
</div>
</div> </div>
</div> </div>

View file

@ -16,7 +16,7 @@ body {
font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
line-height: 1.45; line-height: 1.45;
font-weight: normal; font-weight: normal;
background: hsl(210,17%,98%); background: hsl(210,14%,97%);
height: 100%; height: 100%;
color: hsl(198,19%,72%); color: hsl(198,19%,72%);
word-wrap: break-word; word-wrap: break-word;
@ -5508,6 +5508,81 @@ output {
} }
} }
.sla {
background: white;
border: 1px solid hsl(199,44%,93%);
color: hsl(206,7%,28%);
display: flex;
flex-wrap: wrap;
padding: 20px;
box-shadow: 0 2px hsl(210,7%,94%);
& + .sla {
margin-top: 17px;
}
&.is-inactive {
box-shadow: none;
position: relative;
top: 2px;
& > *:not(.sla-controls) {
opacity: 0.33;
}
}
h3 {
color: hsl(0,0%,60%);
margin-top: 0;
}
.arrow {
align-self: center;
margin: 25px 50px 0;
.icon {
width: 15px;
height: 24px;
fill: hsl(198,17%,89%);
}
}
.response-times-entry {
display: flex;
.icon {
display: none;
vertical-align: middle;
margin-right: 3px;
&:not(.icon-checkmark) {
}
}
.response-time {
margin-right: 5px;
}
}
.response-times-entry:not(:last-child) {
margin: 0 0 2px;
}
.sla-businessHours {
flex-basis: 100%;
margin: 20px 0;
}
.sla-controls {
flex-basis: 100%;
display: flex;
.sla-edit {
margin-left: auto;
}
}
}
/* /*
---------------- ----------------

View file

@ -98,122 +98,98 @@ class ApplicationController < ActionController::Base
def authentication_check_only(auth_param) def authentication_check_only(auth_param)
logger.debug 'authentication_check' logger.debug 'authentication_check'
session[:request_type] = 1
#logger.debug params.inspect #logger.debug params.inspect
#logger.debug session.inspect #logger.debug session.inspect
#logger.debug cookies.inspect #logger.debug cookies.inspect
# check http basic auth # already logged in, early exit
authenticate_with_http_basic do |username, password| if session.id && session[:user_id]
logger.debug 'http basic auth check' userdata = User.find( session[:user_id] )
session[:request_type] = 2 current_user_set(userdata)
userdata = User.authenticate( username, password ) return {
message = '' auth: true
if !userdata }
message = 'authentication failed' end
end
# return auth ok error_message = 'authentication failed'
if message == ''
# remember user # check logon session
session[:user_id] = userdata.id if params['logon_session']
logon_session = ActiveRecord::SessionStore::Session.where( session_id: params['logon_session'] ).first
# set basic auth user to current user # set logon session user to current user
if logon_session
userdata = User.find( logon_session.data[:user_id] )
current_user_set(userdata) current_user_set(userdata)
session[:persistent] = true
return { return {
auth: true auth: true
} }
end end
# return auth not ok error_message = 'no valid session, user_id'
end
# check sso
sso_userdata = User.sso(params)
if sso_userdata
current_user_set(sso_userdata)
session[:persistent] = true
return { return {
auth: false, auth: true
message: message,
} }
end end
# check logon session # check http basic auth
if params['logon_session'] authenticate_with_http_basic do |username, password|
logon_session = ActiveRecord::SessionStore::Session.where( session_id: params['logon_session'] ).first logger.debug "http basic auth check '#{username}'"
if logon_session
userdata = User.find( logon_session.data[:user_id] )
end
session[:request_type] = 3 userdata = User.authenticate( username, password )
# set logon session user to current user next if !userdata
# set basic auth user to current user
current_user_set(userdata) current_user_set(userdata)
return { return {
auth: true auth: true
} }
end end
# check sso
if !session[:user_id]
user = User.sso(params)
# Log the authorizing user in.
if user
session[:user_id] = user.id
end
end
# check token # check token
if auth_param[:token_action] if auth_param[:token_action]
authenticate_with_http_token do |token, options| authenticate_with_http_token do |token, _options|
logger.debug 'token auth check' logger.debug "token auth check #{token}"
session[:request_type] = 4
userdata = Token.check( userdata = Token.check(
action: auth_param[:token_action], action: auth_param[:token_action],
name: token, name: token,
) )
message = '' next if !userdata
if !userdata
message = 'authentication failed'
end
# return auth ok # set token user to current user
if message == '' current_user_set(userdata)
# remember user
session[:user_id] = userdata.id
# set token user to current user
current_user_set(userdata)
return {
auth: true
}
end
# return auth not ok
return { return {
auth: false, auth: true
message: message,
} }
end end
end end
# return auth not ok (no session exists) logger.debug error_message
if !session[:user_id]
logger.debug 'no valid session, user_id'
message = 'no valid session, user_id'
return {
auth: false,
message: message,
}
end
{ {
auth: true auth: false,
message: error_message,
} }
end end
def authentication_check( auth_param = { basic_auth_promt: false } ) def authentication_check( auth_param = {} )
result = authentication_check_only(auth_param) result = authentication_check_only(auth_param)
# check if basic_auth fallback is possible # check if basic_auth fallback is possible
@ -233,6 +209,9 @@ class ApplicationController < ActionController::Base
return false return false
end end
# store current user id into the session
session[:user_id] = current_user.id
# return auth ok # return auth ok
true true
end end

View file

@ -54,6 +54,10 @@ class SessionsController < ApplicationController
# ) # )
end end
# sessions created via this
# controller are persistent
session[:persistent] = true
# return new session data # return new session data
render status: :created, render status: :created,
json: { json: {

View file

@ -13,15 +13,17 @@ class Observer::Session < ActiveRecord::Observer
check(record) check(record)
end end
# move the persistent attribute from the sub structure
# to the first level so it gets stored in the database
# column to make the cleanup lookup more performant
def check(record) def check(record)
return if !record.data return if !record.data
return if record[:request_type] return if record[:persistent]
# remember request type return if !record.data['persistent']
return if !record.data['request_type']
record[:request_type] = record.data['request_type'] record[:persistent] = record.data['persistent']
record.data.delete('request_type') record.data.delete('persistent')
end end
end end

View file

@ -21,7 +21,7 @@ class Token < ActiveRecord::Base
return return
end end
# return token if valid # return token user
token.user token.user
end end

Binary file not shown.

View file

@ -0,0 +1,24 @@
class SessionChanges < ActiveRecord::Migration
def up
ActiveRecord::SessionStore::Session.delete_all
remove_index :sessions, :request_type
remove_column :sessions, :request_type
add_column :sessions, :persistent, :boolean, null: true
add_index :sessions, :persistent
end
def down
ActiveRecord::SessionStore::Session.delete_all
remove_index :sessions, :persistent
remove_column :sessions, :persistent
add_column :sessions, :request_type, :integer, null: true
add_index :sessions, :request_type
end
end

View file

@ -56,6 +56,8 @@ module ICal::Ticket
events_data = [] events_data = []
tickets.each do |ticket| tickets.each do |ticket|
next if !ticket.pending_time
event_data = {} event_data = {}
# rubocop:disable Rails/TimeZone # rubocop:disable Rails/TimeZone
@ -86,6 +88,8 @@ module ICal::Ticket
events_data = [] events_data = []
tickets.each do |ticket| tickets.each do |ticket|
next if !ticket.escalation_time
event_data = {} event_data = {}
# rubocop:disable Rails/TimeZone # rubocop:disable Rails/TimeZone

View file

@ -29,7 +29,7 @@ module SessionHelper
def self.cleanup_expired def self.cleanup_expired
# delete temp. sessions # delete temp. sessions
ActiveRecord::SessionStore::Session.where('request_type IS NULL AND updated_at < ?', Time.zone.now - 1.days ).delete_all ActiveRecord::SessionStore::Session.where('persistent IS NULL AND updated_at < ?', Time.zone.now - 1.days ).delete_all
# web sessions older the x days # web sessions older the x days
ActiveRecord::SessionStore::Session.where('updated_at < ?', Time.zone.now - 90.days ).delete_all ActiveRecord::SessionStore::Session.where('updated_at < ?', Time.zone.now - 90.days ).delete_all