redmine-ldap-config/app/views/ldap_config/index.html.erb
ioresponse e7dd7b0f19 Initial commit: Redmine LDAP Config Plugin
🤖 Generated with Claude Code
2025-12-23 00:21:35 +09:00

193 lines
6.2 KiB
Plaintext

<h2>LDAP Configuration</h2>
<%= javascript_tag do %>
var currentPreset = null;
function domainToDC(domain) {
if (!domain) return '';
return domain.split('.').map(function(part) {
return 'dc=' + part;
}).join(',');
}
function updateFromDomain() {
var domain = document.getElementById('domain_input').value;
if (!currentPreset || !domain) return;
var dc = domainToDC(domain);
var bindUser = document.getElementById('bind_user').value || 'admin';
var baseDN, bindDN, filter, attrLogin;
if (currentPreset === 'freeipa') {
baseDN = 'cn=users,cn=accounts,' + dc;
bindDN = 'uid=' + bindUser + ',cn=users,cn=accounts,' + dc;
filter = '(objectClass=person)';
attrLogin = 'uid';
} else if (currentPreset === 'active_directory') {
baseDN = 'CN=Users,' + dc.toUpperCase().replace(/dc=/g, 'DC=');
bindDN = bindUser + '@' + domain;
filter = '(&(objectClass=user)(!(objectClass=computer)))';
attrLogin = 'sAMAccountName';
} else if (currentPreset === 'openldap') {
baseDN = 'ou=users,' + dc;
bindDN = 'cn=' + bindUser + ',' + dc;
filter = '(objectClass=inetOrgPerson)';
attrLogin = 'uid';
}
document.getElementById('auth_source_ldap_base_dn').value = baseDN;
document.getElementById('auth_source_ldap_account').value = bindDN;
document.getElementById('auth_source_ldap_filter').value = filter;
document.getElementById('auth_source_ldap_attr_login').value = attrLogin;
document.getElementById('auth_source_ldap_attr_firstname').value = 'givenName';
document.getElementById('auth_source_ldap_attr_lastname').value = 'sn';
document.getElementById('auth_source_ldap_attr_mail').value = 'mail';
document.getElementById('auth_source_ldap_onthefly_register').checked = true;
}
function setFieldsReadonly(readonly) {
var fields = ['auth_source_ldap_base_dn', 'auth_source_ldap_account', 'auth_source_ldap_filter',
'auth_source_ldap_attr_login', 'auth_source_ldap_attr_firstname',
'auth_source_ldap_attr_lastname', 'auth_source_ldap_attr_mail'];
fields.forEach(function(id) {
var el = document.getElementById(id);
if (el) {
el.readOnly = readonly;
el.style.backgroundColor = readonly ? '#f0f0f0' : '';
}
});
}
function applyPresetMode(preset) {
currentPreset = preset;
var domainSection = document.getElementById('domain-section');
if (preset && (preset === 'freeipa' || preset === 'active_directory' || preset === 'openldap')) {
domainSection.style.display = 'block';
var names = { 'freeipa': 'FreeIPA', 'active_directory': 'Active Directory', 'openldap': 'OpenLDAP' };
document.getElementById('auth_source_ldap_name').value = names[preset];
setFieldsReadonly(true);
document.getElementById('domain_input').value = '';
document.getElementById('bind_user').value = 'admin';
} else {
domainSection.style.display = 'none';
setFieldsReadonly(false);
document.getElementById('auth_source_ldap_name').value = '';
}
}
function testLdapConnection() {
var form = document.getElementById('ldap-form');
var formData = new FormData(form);
var testBtn = document.getElementById('test-btn');
var resultDiv = document.getElementById('test-result');
testBtn.disabled = true;
testBtn.value = 'Testing...';
resultDiv.innerHTML = '';
fetch('<%= url_for(controller: 'ldap_config', action: 'test_connection') %>', {
method: 'POST',
body: formData,
headers: {
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
}
})
.then(function(response) { return response.json(); })
.then(function(data) {
testBtn.disabled = false;
testBtn.value = 'Test Connection';
if (data.success) {
resultDiv.innerHTML = '<span style="color: green; font-weight: bold;">OK: ' + data.message + '</span>';
} else {
resultDiv.innerHTML = '<span style="color: red; font-weight: bold;">FAIL: ' + data.message + '</span>';
}
})
.catch(function(error) {
testBtn.disabled = false;
testBtn.value = 'Test Connection';
resultDiv.innerHTML = '<span style="color: red;">Error: ' + error + '</span>';
});
}
$(document).ready(function() {
$('#domain_input').on('keyup change', function() {
updateFromDomain();
});
$('#bind_user').on('keyup change', function() {
updateFromDomain();
});
$('#preset').on('change', function() {
applyPresetMode(this.value);
});
});
<% end %>
<% if @ldap_sources.any? %>
<h3>Existing LDAP Sources</h3>
<table class="list">
<thead>
<tr>
<th>Name</th>
<th>Host</th>
<th>Port</th>
<th>TLS</th>
<th>Base DN</th>
<th>On-the-fly</th>
<th>Users</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% @ldap_sources.each do |ldap| %>
<tr>
<td><strong><%= ldap.name %></strong></td>
<td><%= ldap.host %></td>
<td><%= ldap.port %></td>
<td><%= ldap.tls ? 'Yes' : 'No' %></td>
<td><code style="font-size: 11px;"><%= truncate(ldap.base_dn, length: 40) %></code></td>
<td><%= ldap.onthefly_register ? 'Yes' : 'No' %></td>
<td><%= ldap.users.count %></td>
<td>
<%= link_to 'Edit', ldap_config_edit_path(ldap), class: 'icon icon-edit' %>
<%= link_to 'Delete', ldap_config_delete_path(ldap),
method: :delete,
data: { confirm: 'Are you sure?' },
class: 'icon icon-del' %>
</td>
</tr>
<% end %>
</tbody>
</table>
<hr />
<% end %>
<h3>Add New LDAP Source</h3>
<div class="box">
<p>
<label for="preset">Quick Setup (Preset):</label>
<select id="preset">
<option value="">-- Manual Configuration --</option>
<option value="freeipa">FreeIPA</option>
<option value="active_directory">Active Directory</option>
<option value="openldap">OpenLDAP</option>
</select>
<em class="info">(Select preset for simplified setup)</em>
</p>
</div>
<%= form_for @ldap, url: { controller: 'ldap_config', action: 'create' },
html: { id: 'ldap-form', class: 'tabular' } do |f| %>
<%= render partial: 'ldap_form', locals: { f: f } %>
<p style="margin-top: 15px;">
<%= f.submit 'Create', class: 'button-positive' %>
<input type="button" id="test-btn" value="Test Connection" onclick="testLdapConnection()" class="button" />
<span id="test-result" style="margin-left: 10px;"></span>
</p>
<% end %>