From cb7809cef938d20d255095fff83465ebafe902f0 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Sat, 17 Aug 2013 23:48:01 +0200 Subject: [PATCH] Rewrite of Auth and SSO module layer. --- app/models/user.rb | 82 ++++---------------------------------------- db/seeds.rb | 4 +-- lib/auth.rb | 63 ++++++++++++++++++++++++++++++++++ lib/auth/internal.rb | 6 ++-- lib/auth/ldap.rb | 6 ++-- lib/auth/otrs.rb | 7 ++-- lib/auth/test.rb | 6 ++-- lib/sso.rb | 63 ++++++++++++++++++++++++++++++++++ lib/sso/env.rb | 6 ++-- lib/sso/otrs.rb | 6 ++-- 10 files changed, 153 insertions(+), 96 deletions(-) create mode 100644 lib/auth.rb create mode 100644 lib/sso.rb diff --git a/app/models/user.rb b/app/models/user.rb index 393e47d7a..3fb778fce 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -60,96 +60,26 @@ class User < ApplicationModel return false end - # use auth backends - config = [ - { - :adapter => 'internal', - }, - { - :adapter => 'test', - }, - ] - Setting.where( :area => 'Security::Authentication' ).each {|setting| - if setting.state[:value] - config.push setting.state[:value] - end - } - - # try to login against configure auth backends - user_auth = nil - config.each {|config_item| - next if !config_item[:adapter] - next if config_item.class == TrueClass - file = "auth/#{config_item[:adapter]}" - require file - user_auth = Auth.const_get("#{config_item[:adapter].to_s.upcase}").check( username, password, config_item, user ) - - # auth ok - if user_auth - - # remember last login date - user_auth.update_last_login - - # reset login failed - user_auth.login_failed = 0 - user_auth.save - - return user_auth - end - } + user_auth = Auth.check( username, password, user ) # set login failed +1 if !user_auth && user + sleep 1 user.login_failed = user.login_failed + 1 user.save end - # auth failed - sleep 1 + # auth ok return user_auth end def self.sso(params) - # use auth backends - config = [ - { - :adapter => 'env', - }, - { - :adapter => 'otrs', - }, - ] - # Setting.where( :area => 'Security::Authentication' ).each {|setting| - # if setting.state[:value] - # config.push setting.state[:value] - # end - # } - # try to login against configure auth backends - user_auth = nil - config.each {|config_item| - next if !config_item[:adapter] - next if config_item.class == TrueClass - file = "sso/#{config_item[:adapter]}" - require file - user_auth = SSO.const_get("#{config_item[:adapter].to_s.upcase}").check( params, config_item ) + user_auth = Sso.check( params, user ) + return if !user_auth - # auth ok - if user_auth - - # remember last login date - user_auth.update_last_login - - # reset login failed - user_auth.login_failed = 0 - user_auth.save - - return user_auth - end - } - - return false + return user_auth end def self.create_from_hash!(hash) diff --git a/db/seeds.rb b/db/seeds.rb index 0e373b66f..597b082bf 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -250,7 +250,7 @@ Setting.create_if_not_exists( :area => 'Security::Authentication', :description => 'Enables user authentication via OTRS.', :state => { - :adapter => 'otrs', + :adapter => 'Auth::Otrs', :required_group_ro => 'stats', :group_rw_role_map => { 'admin' => 'Admin', @@ -271,7 +271,7 @@ Setting.create_if_not_exists( :area => 'Security::Authentication', :description => 'Enables user authentication via LDAP.', :state => { - :adapter => 'ldap', + :adapter => 'Auth::Ldap', :host => 'localhost', :port => 389, :bind_dn => 'cn=Manager,dc=example,dc=org', diff --git a/lib/auth.rb b/lib/auth.rb new file mode 100644 index 000000000..85b1e0867 --- /dev/null +++ b/lib/auth.rb @@ -0,0 +1,63 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +class Auth < ApplicationLib + +=begin + +authenticate user via username and password + + result = Auth.check( username, password, user ) + +returns + + result = user_model # if authentication was successfully + +=end + + def self.check(username, password, user) + + # use std. auth backends + config = [ + { + :adapter => 'Auth::Internal', + }, + { + :adapter => 'Auth::Test', + }, + ] + + # added configured backends + Setting.where( :area => 'Security::Authentication' ).each {|setting| + if setting.state[:value] + config.push setting.state[:value] + end + } + + # try to login against configure auth backends + user_auth = nil + config.each {|config_item| + next if !config_item[:adapter] + + # load backend + backend = self.load_adapter( config_item[:adapter] ) + return if !backend + + user_auth = backend.check( username, password, config_item, user ) + + # auth ok + if user_auth + + # remember last login date + user_auth.update_last_login + + # reset login failed + user_auth.login_failed = 0 + user_auth.save + + return user_auth + end + } + return + + end +end diff --git a/lib/auth/internal.rb b/lib/auth/internal.rb index 923eb3136..48d69bc8b 100644 --- a/lib/auth/internal.rb +++ b/lib/auth/internal.rb @@ -1,6 +1,6 @@ -module Auth -end -module Auth::INTERNAL +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +module Auth::Internal def self.check( username, password, config, user ) # return if no user exists diff --git a/lib/auth/ldap.rb b/lib/auth/ldap.rb index 99dcea5fe..f72426973 100644 --- a/lib/auth/ldap.rb +++ b/lib/auth/ldap.rb @@ -1,8 +1,8 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + require 'net/ldap' -module Auth -end -module Auth::LDAP +module Auth::Ldap def self.check( username, password, config, user ) scope = Net::LDAP::SearchScope_WholeSubtree diff --git a/lib/auth/otrs.rb b/lib/auth/otrs.rb index a0ad88336..3219d86cb 100644 --- a/lib/auth/otrs.rb +++ b/lib/auth/otrs.rb @@ -1,7 +1,8 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + require 'import/otrs' -module Auth -end -module Auth::OTRS + +module Auth::Otrs def self.check( username, password, config, user ) endpoint = Setting.get('import_otrs_endpoint') diff --git a/lib/auth/test.rb b/lib/auth/test.rb index cf68a85be..a06a2f330 100644 --- a/lib/auth/test.rb +++ b/lib/auth/test.rb @@ -1,6 +1,6 @@ -module Auth -end -module Auth::TEST +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +module Auth::Test def self.check( username, password, config, user ) # development systems diff --git a/lib/sso.rb b/lib/sso.rb new file mode 100644 index 000000000..4715723e9 --- /dev/null +++ b/lib/sso.rb @@ -0,0 +1,63 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +class Sso < ApplicationLib + +=begin + +authenticate user via username and password + + result = Sso.check( params, config_item ) + +returns + + result = user_model # if authentication was successfully + +=end + + def self.check(params) + + # use std. auth backends + config = [ + { + :adapter => 'Sso::Env', + }, + { + :adapter => 'Sso::Otrs', + }, + ] + + # added configured backends + Setting.where( :area => 'Security::SSO' ).each {|setting| + if setting.state[:value] + config.push setting.state[:value] + end + } + + # try to login against configure auth backends + user_auth = nil + config.each {|config_item| + next if !config_item[:adapter] + + # load backend + backend = self.load_adapter( config_item[:adapter] ) + return if !backend + + user_auth = backend.check( params, config_item ) + + # auth ok + if user_auth + + # remember last login date + user_auth.update_last_login + + # reset login failed + user_auth.login_failed = 0 + user_auth.save + + return user_auth + end + } + return + + end +end diff --git a/lib/sso/env.rb b/lib/sso/env.rb index 6904719e1..633658ced 100644 --- a/lib/sso/env.rb +++ b/lib/sso/env.rb @@ -1,6 +1,6 @@ -module SSO -end -module SSO::ENV +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +module Sso::Env def self.check( params, config_item ) # try to find user based on login diff --git a/lib/sso/otrs.rb b/lib/sso/otrs.rb index 349ab47cf..660fa3e38 100644 --- a/lib/sso/otrs.rb +++ b/lib/sso/otrs.rb @@ -1,6 +1,6 @@ -module SSO -end -module SSO::OTRS +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +module Sso::Otrs def self.check( params, config_item ) endpoint = Setting.get('import_otrs_endpoint')