Some minor fixes
This commit is contained in:
+4
-4
@@ -10,7 +10,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
REDMINE_DB_MYSQL: db
|
REDMINE_DB_MYSQL: db
|
||||||
REDMINE_SECRET_KEY_BASE: supersecretkey
|
REDMINE_SECRET_KEY_BASE: supersecretkey
|
||||||
REDMINE_PLUGINS_MIGRATE: true
|
REDMINE_PLUGINS_MIGRATE: "true"
|
||||||
env_file:
|
env_file:
|
||||||
- db.env
|
- db.env
|
||||||
volumes:
|
volumes:
|
||||||
@@ -34,17 +34,17 @@ volumes:
|
|||||||
db:
|
db:
|
||||||
driver_opts:
|
driver_opts:
|
||||||
type: none
|
type: none
|
||||||
device: /media/docker/nc-db
|
device: /tmp/docker/redmine-db
|
||||||
o: bind
|
o: bind
|
||||||
redmine-files:
|
redmine-files:
|
||||||
driver_opts:
|
driver_opts:
|
||||||
type: none
|
type: none
|
||||||
device: /media/docker/nc-data
|
device: /tmp/docker/redmine-files
|
||||||
o: bind
|
o: bind
|
||||||
redmine-logs:
|
redmine-logs:
|
||||||
driver_opts:
|
driver_opts:
|
||||||
type: none
|
type: none
|
||||||
device: /media/docker/nc-data
|
device: /tmp/docker/redmine-logs
|
||||||
o: bind
|
o: bind
|
||||||
|
|
||||||
# openldap:
|
# openldap:
|
||||||
|
|||||||
+20
-3
@@ -14,8 +14,8 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- db.env
|
- db.env
|
||||||
volumes:
|
volumes:
|
||||||
- /srv/docker/redmine/redmine_mysql:/usr/src/redmine/files
|
- redmine-files:/usr/src/redmine/files
|
||||||
- /srv/docker/redmine/redmine-logs:/var/log/redmine
|
- redmine-logs:/var/log/redmine
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
|
|
||||||
@@ -28,7 +28,24 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- db.env
|
- db.env
|
||||||
volumes:
|
volumes:
|
||||||
- /srv/docker/redmine/mysql:/var/lib/mysql
|
- db:/var/lib/mysql
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
db:
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
device: /tmp/docker/redmine-db
|
||||||
|
o: bind
|
||||||
|
redmine-files:
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
device: /tmp/docker/redmine-files
|
||||||
|
o: bind
|
||||||
|
redmine-logs:
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
device: /tmp/docker/redmine-logs
|
||||||
|
o: bind
|
||||||
|
|
||||||
# openldap:
|
# openldap:
|
||||||
#
|
#
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
FROM redmine:latest-alpine
|
FROM redmine:latest
|
||||||
ENV REDMINE_DB_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
ENV REDMINE_DB_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
||||||
COPY ./redmine_ldap_passwd/. /usr/share/redmine/plugins/
|
ADD ./redmine_ldap_passwd/ /usr/share/redmine/plugins/
|
||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
FROM redmine
|
FROM redmine:latest
|
||||||
ENV REDMINE_DB_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
ENV REDMINE_DB_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
||||||
COPY ./redmine_ldap_passwd/. /usr/share/redmine/plugins/
|
COPY redmine_ldap_passwd /usr/share/redmine/plugins/
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Redmine LDAP Passwd plugin >= Redmine 3.0
|
|
||||||
|
|
||||||
The plugin extends AuthSourceLdap to introduce the ability to recover or change user password.
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* Allows to changed password and update LDAP record.
|
|
||||||
* Allows to recover password and update LDAP record.
|
|
||||||
|
|
||||||
**Notes**
|
|
||||||
|
|
||||||
* The solution has been tested on MS Active Directory only. It works only with SSL connection, please ensure SSL is configured on Active Directory side.
|
|
||||||
|
|
||||||
### Install
|
|
||||||
|
|
||||||
1. Follow Redmine [plugin installation instructions](http://www.redmine.org/projects/redmine/wiki/Plugins#Installing-a-plugin).
|
|
||||||
2. Add new LDAP connection and check the records in 'auth_sources' making sure column 'type'='AuthSourceLdapPasswd'. If it is not, update the record manually executing the SQL query.
|
|
||||||
3. Assign new LDAP connection to the specific users you would like to provide access through LDAP to.
|
|
||||||
|
|
||||||
### Uninstall
|
|
||||||
|
|
||||||
1. Follow Redmine [plugin uninstall instructions](http://www.redmine.org/projects/redmine/wiki/Plugins#Uninstalling-a-plugin).
|
|
||||||
|
|
||||||
### Changelog
|
|
||||||
|
|
||||||
* **3.0 (2016-05-31)**
|
|
||||||
* Initial version released.
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
class AuthSourceLdapPasswd < AuthSourceLdap
|
|
||||||
def allow_password_changes?
|
|
||||||
self.tls
|
|
||||||
end
|
|
||||||
|
|
||||||
def change_user_password(user, password, new_password)
|
|
||||||
return false unless AuthSourceLdapPasswd.change_password_allowed?(user)
|
|
||||||
|
|
||||||
attrs = get_user_dn(user.login, password)
|
|
||||||
if attrs && attrs[:dn]
|
|
||||||
if self.account && self.account.include?("$login")
|
|
||||||
ldap_con = initialize_ldap_con(self.account.sub("$login", Net::LDAP::DN.escape(user.login)), password)
|
|
||||||
else
|
|
||||||
ldap_con = initialize_ldap_con(self.account, self.account_password)
|
|
||||||
end
|
|
||||||
|
|
||||||
ops = [[:replace, :unicodePwd, AuthSourceLdapPasswd.str2unicodePwd(new_password)]]
|
|
||||||
ldap_con.modify :dn => attrs[:dn], :operations => ops
|
|
||||||
|
|
||||||
result = ldap_con.get_operation_result
|
|
||||||
if result.code == 0
|
|
||||||
user.passwd_changed_on = Time.now.change(:usec => 0)
|
|
||||||
user.save
|
|
||||||
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.str2unicodePwd(str)
|
|
||||||
('"' + str + '"').encode("utf-16le").force_encoding("utf-8")
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.change_password_allowed?(user)
|
|
||||||
return false if user.nil?
|
|
||||||
AuthSourceLdapPasswd.name.eql?(user.auth_source.type)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.is_password_valid(password)
|
|
||||||
return false if password.nil? || password.length < 7
|
|
||||||
|
|
||||||
s = 0
|
|
||||||
contains = [
|
|
||||||
password.match(/\p{Lower}/) ? 1 : 0,
|
|
||||||
password.match(/\p{Upper}/) ? 1 : 0,
|
|
||||||
password.match(/\p{Digit}/) ? 1 : 0,
|
|
||||||
password.match(/[^\\w\\d]+/) ? 1 : 0
|
|
||||||
]
|
|
||||||
contains.each { |a| s += a }
|
|
||||||
|
|
||||||
return s >= 3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
en:
|
|
||||||
notice_new_password_and_confirmation_different: The new password is different from the confirmation password
|
|
||||||
notice_new_password_format: "1. The password should be at least seven characters long. 2. The password should contain characters from at least three of the following four categories: (a) English uppercase characters (A - Z) (b) English lowercase characters (a - z) (c) Base 10 digits (0 - 9) (d) Non-alphanumeric (For example: !, $, or %). 3. The password shouldn't contain three or more characters from the user's account name."
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
require 'redmine'
|
|
||||||
|
|
||||||
require_dependency 'redmine_ldap_passwd_my_controller_patch'
|
|
||||||
require_dependency 'redmine_ldap_passwd_auth_sources_helper_patch'
|
|
||||||
require_dependency 'redmine_ldap_passwd_account_controller_patch'
|
|
||||||
|
|
||||||
Redmine::Plugin.register :redmine_ldap_passwd do
|
|
||||||
name 'Redmine LDAP Change Password'
|
|
||||||
author 'Yura Zaplavnov'
|
|
||||||
description 'The plugin extends AuthSourceLdap to introduce the ability to recover or change user password.'
|
|
||||||
version '3.0.1'
|
|
||||||
url 'https://github.com/xeagle2/redmine_ldap_passwd'
|
|
||||||
author_url 'https://github.com/xeagle2'
|
|
||||||
end
|
|
||||||
|
|
||||||
require 'dispatcher' unless Rails::VERSION::MAJOR >= 3
|
|
||||||
|
|
||||||
if Rails::VERSION::MAJOR >= 5
|
|
||||||
ActiveSupport::Reloader.to_prepare do
|
|
||||||
MyController.send(:include, RedmineLdapPasswd::MyControllerPatch)
|
|
||||||
AuthSourcesHelper.send(:include, RedmineLdapPasswd::AuthSourcesHelperPatch)
|
|
||||||
AccountController.send(:include, RedmineLdapPasswd::AccountControllerPatch)
|
|
||||||
end
|
|
||||||
elsif Rails::VERSION::MAJOR >= 3
|
|
||||||
ActionDispatch::Callbacks.to_prepare do
|
|
||||||
MyController.send(:include, RedmineLdapPasswd::MyControllerPatch)
|
|
||||||
AuthSourcesHelper.send(:include, RedmineLdapPasswd::AuthSourcesHelperPatch)
|
|
||||||
AccountController.send(:include, RedmineLdapPasswd::AccountControllerPatch)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Dispatcher.to_prepare do
|
|
||||||
MyController.send(:include, RedmineLdapPasswd::MyControllerPatch)
|
|
||||||
AuthSourcesHelper.send(:include, RedmineLdapPasswd::AuthSourcesHelperPatch)
|
|
||||||
AccountController.send(:include, RedmineLdapPasswd::AccountControllerPatch)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-66
@@ -1,66 +0,0 @@
|
|||||||
module RedmineLdapPasswd
|
|
||||||
module AccountControllerPatch
|
|
||||||
def self.included(base)
|
|
||||||
base.send(:extend, ClassMethods)
|
|
||||||
base.send(:include, InstanceMethods)
|
|
||||||
|
|
||||||
base.class_eval do
|
|
||||||
unloadable # Send unloadable so it will not be unloaded in development
|
|
||||||
|
|
||||||
if Rails::VERSION::MAJOR >= 5
|
|
||||||
alias_method :lost_password_without_extension, :lost_password
|
|
||||||
alias_method :lost_password, :lost_password_with_extension
|
|
||||||
else
|
|
||||||
alias_method :lost_password, :extension
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module ClassMethods
|
|
||||||
end
|
|
||||||
|
|
||||||
module InstanceMethods
|
|
||||||
def lost_password_with_extension
|
|
||||||
if params[:token]
|
|
||||||
@token = Token.find_token("recovery", params[:token].to_s)
|
|
||||||
if @token.nil? || @token.expired?
|
|
||||||
redirect_to home_url
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
@user = @token.user
|
|
||||||
unless @user && @user.active?
|
|
||||||
redirect_to home_url
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if request.post?
|
|
||||||
if params[:new_password_confirmation] != params[:new_password]
|
|
||||||
flash.now[:error] = l(:notice_new_password_and_confirmation_different)
|
|
||||||
elsif !AuthSourceLdapPasswd.is_password_valid (params[:new_password])
|
|
||||||
flash.now[:error] = l(:notice_new_password_format)
|
|
||||||
else
|
|
||||||
r = @user.auth_source.change_user_password(@user, '', params[:new_password])
|
|
||||||
|
|
||||||
if r == true
|
|
||||||
flash[:notice] = l(:notice_account_password_updated)
|
|
||||||
redirect_to signin_path
|
|
||||||
elsif r == false
|
|
||||||
lost_password_without_extension
|
|
||||||
else
|
|
||||||
flash.now[:error] = r.message
|
|
||||||
end
|
|
||||||
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
render :template => "account/password_recovery"
|
|
||||||
return
|
|
||||||
else
|
|
||||||
lost_password_without_extension
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-25
@@ -1,25 +0,0 @@
|
|||||||
module RedmineLdapPasswd
|
|
||||||
module AuthSourcesHelperPatch
|
|
||||||
def self.included(base) # :nodoc:
|
|
||||||
base.send(:include, InstanceMethods)
|
|
||||||
|
|
||||||
base.class_eval do
|
|
||||||
unloadable # Send unloadable so it will not be unloaded in development
|
|
||||||
|
|
||||||
if Rails::VERSION::MAJOR >= 5
|
|
||||||
alias_method :auth_source_partial_name_without_ignored_passwd, :auth_source_partial_name
|
|
||||||
alias_method :auth_source_partial_name, :auth_source_partial_name_with_ignored_passwd
|
|
||||||
else
|
|
||||||
alias_method :auth_source_partial_name, :ignored_passwd
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module InstanceMethods
|
|
||||||
# Make sure AuthSourceLdapPasswd is loaded with the same form as AuthSourceLdap
|
|
||||||
def auth_source_partial_name_with_ignored_passwd(auth_source)
|
|
||||||
"form_#{auth_source.class.name.underscore}".chomp('_passwd')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
module RedmineLdapPasswd
|
|
||||||
module MyControllerPatch
|
|
||||||
def self.included(base)
|
|
||||||
base.send(:extend, ClassMethods)
|
|
||||||
base.send(:include, InstanceMethods)
|
|
||||||
|
|
||||||
base.class_eval do
|
|
||||||
unloadable # Send unloadable so it will not be unloaded in development
|
|
||||||
|
|
||||||
if Rails::VERSION::MAJOR >= 5
|
|
||||||
alias_method :password_without_extension, :password
|
|
||||||
alias_method :password, :password_with_extension
|
|
||||||
else
|
|
||||||
alias_method_chain :password, :extension
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module ClassMethods
|
|
||||||
end
|
|
||||||
|
|
||||||
module InstanceMethods
|
|
||||||
def password_with_extension
|
|
||||||
@user = User.current
|
|
||||||
|
|
||||||
unless @user.change_password_allowed?
|
|
||||||
flash[:error] = l(:notice_can_t_change_password)
|
|
||||||
redirect_to my_account_path
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if request.post?
|
|
||||||
if !@user.check_password?(params[:password])
|
|
||||||
flash.now[:error] = l(:notice_account_wrong_password)
|
|
||||||
elsif params[:password] == params[:new_password]
|
|
||||||
flash.now[:error] = l(:notice_new_password_must_be_different)
|
|
||||||
elsif params[:new_password_confirmation] != params[:new_password]
|
|
||||||
flash.now[:error] = l(:notice_new_password_and_confirmation_different)
|
|
||||||
elsif AuthSourceLdapPasswd.change_password_allowed?(@user)
|
|
||||||
if AuthSourceLdapPasswd.is_password_valid (params[:new_password])
|
|
||||||
r = @user.auth_source.change_user_password(@user, params[:password], params[:new_password])
|
|
||||||
|
|
||||||
if r == true
|
|
||||||
session[:ctime] = User.current.passwd_changed_on.utc.to_i
|
|
||||||
flash[:notice] = l(:notice_account_password_updated)
|
|
||||||
redirect_to my_account_path
|
|
||||||
elsif r == false
|
|
||||||
password_without_extension
|
|
||||||
else
|
|
||||||
flash.now[:error] = r.message
|
|
||||||
end
|
|
||||||
else
|
|
||||||
flash.now[:error] = l(:notice_new_password_format)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
password_without_extension
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rescue Net::LDAP::LdapError => e
|
|
||||||
raise AuthSourceException.new(e.message)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Reference in New Issue
Block a user