Dépôt officiel du code source de l'ERP OpenConcerto
Rev 156 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.sql.users;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.TM;
import org.openconcerto.sql.element.BaseSQLComponent;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.request.ComboSQLRequest;
import org.openconcerto.sql.sqlobject.itemview.SimpleRowItemView;
import org.openconcerto.sql.ui.IColorChooser;
import org.openconcerto.sql.ui.Login;
import org.openconcerto.sql.view.QuickAssignPanel;
import org.openconcerto.sql.view.list.ITableModel;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.sql.view.list.SQLTableElement;
import org.openconcerto.sql.view.list.SQLTableModelColumn;
import org.openconcerto.sql.view.list.SQLTableModelSource;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.ISpinner;
import org.openconcerto.ui.ISpinnerIntegerModel;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.component.InteractionMode;
import org.openconcerto.ui.valuewrapper.TextValueWrapper;
import org.openconcerto.ui.warning.JLabelWarning;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.ListMap;
import org.openconcerto.utils.cc.ITransformer;
import org.openconcerto.utils.checks.ValidState;
import org.openconcerto.utils.text.SimpleDocumentListener;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.table.DefaultTableCellRenderer;
// FIXME Login user unique ?
public class UserCommonSQLElement extends SQLElement {
/**
* Set this system property to "true" if this should generate old style passwords.
*/
public static final String LEGACY_PASSWORDS = "org.openconcerto.sql.legacyPasswords";
private final boolean familyNameFirst;
public UserCommonSQLElement(final DBRoot root) {
this(root, false);
}
public UserCommonSQLElement(final DBRoot root, final boolean familyNameFirst) {
// allow subclass to keep same code
super(root.findTable("USER_COMMON"), null, "sql.user");
this.familyNameFirst = familyNameFirst;
}
@Override
protected List<String> getListFields() {
final List<String> l = new ArrayList<>(5);
if (this.familyNameFirst) {
l.add("NOM");
l.add("PRENOM");
} else {
l.add("PRENOM");
l.add("NOM");
}
l.add("LOGIN");
if (getTable().contains("DISABLED")) {
l.add("DISABLED");
}
if (getTable().contains("OUT")) {
l.add("OUT");
}
return l;
}
@Override
protected synchronized void _initTableSource(final SQLTableModelSource res) {
super._initTableSource(res);
// current user in bold
for (final SQLTableModelColumn col : res.getColumns()) {
if (col.getValueClass().equals(String.class)) {
col.setRenderer(new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) {
final JLabel res = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
final boolean isCurrentUser = ITableModel.getLine(table.getModel(), row).getRow().getID() == UserManager.getUserID();
final int targetStyle = isCurrentUser ? Font.BOLD : Font.PLAIN;
if ((res.getFont().getStyle() & targetStyle) == 0) {
res.setFont(res.getFont().deriveFont(targetStyle));
}
return res;
}
});
}
}
}
@Override
protected List<String> getComboFields() {
final List<String> l = new ArrayList<>(2);
if (this.familyNameFirst) {
l.add("NOM");
l.add("PRENOM");
} else {
l.add("PRENOM");
l.add("NOM");
}
return l;
}
@Override
protected void _initComboRequest(final ComboSQLRequest req) {
super._initComboRequest(req);
req.setFieldSeparator(" ");
}
@Override
public ListMap<String, String> getShowAs() {
return ListMap.singleton(null, "PRENOM", "NOM");
}
/*
* (non-Javadoc)
*
* @see org.openconcerto.devis.SQLElement#getComponent()
*/
@Override
public SQLComponent createComponent() {
return new UserSQLComponent(this);
}
protected static class UserSQLComponent extends BaseSQLComponent {
private JPasswordField passField;
private JPasswordField passFieldConfirm;
private JPanel panelWarning;
private final SQLElement accessSocieteElem;
private QuickAssignPanel table;
// TODO transform into real SQLRowItemView
private final JTextField encryptedPass = new JTextField();
private JCheckBox noCompanyLimitCheckBox;
{
final SQLTable t = getTable().getDBSystemRoot().getGraph().findReferentTable(getTable(), "ACCES_SOCIETE");
this.accessSocieteElem = t == null ? null : getDirectory().getElement(t);
}
protected UserSQLComponent(final SQLElement element) {
super(element);
}
protected final JPasswordField getPassField() {
return this.passField;
}
protected final JPasswordField getPassFieldConfirm() {
return this.passFieldConfirm;
}
@Override
public void addViews() {
final GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(0, 0, 0, 0);
c.gridx = 0;
c.gridy = 0;
c.weightx = 0;
c.weighty = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.WEST;
this.panelWarning = new JPanel(new GridBagLayout());
this.panelWarning.setBorder(BorderFactory.createEmptyBorder());
final JLabelWarning labelWarning = new JLabelWarning();
this.panelWarning.add(labelWarning, c);
final JLabel labelTextWarning = new JLabel(TM.tr("user.passwordsDontMatch.short"));
c.gridx++;
this.panelWarning.add(labelTextWarning, c);
final GridBagLayout layout = new GridBagLayout();
this.setLayout(layout);
// Login
c.gridx = 0;
c.insets = new Insets(2, 2, 1, 2);
final JLabel labelLogin = new JLabel(getLabelFor("LOGIN"), SwingConstants.RIGHT);
this.add(labelLogin, c);
final JTextField textLogin = new JTextField();
c.gridx++;
DefaultGridBagConstraints.lockMinimumSize(textLogin);
c.weightx = 1;
this.add(textLogin, c);
// Warning
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridx++;
c.insets = new Insets(0, 0, 0, 0);
this.add(this.panelWarning, c);
this.panelWarning.setVisible(false);
// Pass
c.gridy++;
c.gridwidth = 1;
c.gridx = 0;
c.weightx = 0;
c.insets = new Insets(2, 2, 1, 2);
final JLabel labelPass = new JLabel(getLabelFor("PASSWORD"), SwingConstants.RIGHT);
this.add(labelPass, c);
this.passField = new JPasswordField(15);
c.gridx++;
c.weightx = 1;
DefaultGridBagConstraints.lockMinimumSize(this.getPassField());
this.add(this.getPassField(), c);
// Confirmation password
c.gridx++;
c.weightx = 0;
final JLabel labelConfirmationPass = new JLabel(getLabelFor("PASSWORD_CONFIRM"), SwingConstants.RIGHT);
this.add(labelConfirmationPass, c);
this.passFieldConfirm = new JPasswordField(15);
c.gridx++;
c.weightx = 1;
DefaultGridBagConstraints.lockMinimumSize(this.getPassFieldConfirm());
this.add(this.getPassFieldConfirm(), c);
// Nom
c.gridx = 0;
c.gridy++;
c.weightx = 0;
final JLabel labelNom = new JLabel(getLabelFor("NOM"), SwingConstants.RIGHT);
this.add(labelNom, c);
final JTextField textNom = new JTextField();
c.gridx++;
c.weightx = 1;
this.add(textNom, c);
// Prenom
c.gridx++;
c.weightx = 0;
final JLabel labelPrenom = new JLabel(getLabelFor("PRENOM"), SwingConstants.RIGHT);
this.add(labelPrenom, c);
final JTextField textPrenom = new JTextField();
c.gridx++;
c.weightx = 1;
this.add(textPrenom, c);
// Surnom
c.gridx = 0;
c.gridy++;
c.weightx = 0;
final JLabel labelSurnom = new JLabel(getLabelFor("SURNOM"), SwingConstants.RIGHT);
this.add(labelSurnom, c);
final JTextField textSurnom = new JTextField();
c.gridx++;
c.weightx = 1;
this.add(textSurnom, c);
if (this.getTable().contains("ADMIN")) {
final JCheckBox checkAdmin = new JCheckBox(getLabelFor("ADMIN"));
c.gridx++;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 0;
this.add(checkAdmin, c);
this.addView(checkAdmin, "ADMIN");
}
c.gridy++;
c.gridwidth = 1;
c.gridx = 0;
c.weightx = 0;
if (getTable().contains("MAIL")) {
final JLabel labelMail = new JLabel(getLabelFor("MAIL"), SwingConstants.RIGHT);
c.anchor = GridBagConstraints.NORTHWEST;
this.add(labelMail, c);
c.gridx++;
final JTextField textMail = new JTextField();
c.gridwidth = 1;
c.weightx = 1;
this.add(textMail, c);
this.addView(textMail, "MAIL");
}
if (getTable().contains("OUT")) {
c.gridx++;
final JCheckBox boxOut = new JCheckBox(getLabelFor("OUT"));
c.gridwidth = 1;
c.weightx = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
this.add(boxOut, c);
this.addView(boxOut, "OUT");
} else {
if (getTable().contains("DISABLED")) {
c.gridx++;
final JCheckBox boxDisabled = new JCheckBox(getLabelFor("DISABLED"));
c.gridwidth = 1;
c.weightx = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
this.add(boxDisabled, c);
this.addView(boxDisabled, "DISABLED");
}
}
c.gridy++;
if (getTable().contains("COMPTE_NUMERO")) {
final JLabel labelMail = new JLabel(getLabelFor("COMPTE_NUMERO"));
labelMail.setHorizontalAlignment(SwingConstants.RIGHT);
c.anchor = GridBagConstraints.NORTHWEST;
this.add(labelMail, c);
c.gridx++;
final JTextField textMail = new JTextField();
c.gridwidth = 1;
c.weightx = 1;
c.gridy++;
this.add(textMail, c);
this.addView(textMail, "COMPTE_NUMERO");
}
if (getTable().contains("TEL")) {
c.gridx = 0;
final JLabel labelTel = new JLabel(getLabelFor("TEL"), SwingConstants.RIGHT);
c.gridwidth = 1;
c.weightx = 0;
this.add(labelTel, c);
final JTextField fieldTel = new JTextField(20);
c.gridx++;
c.weightx = 1;
this.add(fieldTel, c);
this.addView(fieldTel, "TEL");
}
if (getTable().contains("CALENDAR_USER")) {
c.gridx = 2;
final JCheckBox boxCalUser = new JCheckBox(getLabelFor("CALENDAR_USER"));
c.weightx = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
this.add(boxCalUser, c);
this.addView(boxCalUser, "CALENDAR_USER");
}
if (getTable().contains("COLOR")) {
c.gridy++;
c.gridx = 0;
final JLabel labelTel = new JLabel(getLabelFor("COLOR"), SwingConstants.RIGHT);
c.gridwidth = 1;
c.weightx = 0;
this.add(labelTel, c);
final IColorChooser colorChooser = new IColorChooser(getLabelFor("COLOR"));
c.gridx++;
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(colorChooser, c);
this.addView(colorChooser, "COLOR");
}
final boolean gestionHoraire = false;
if (Configuration.getInstance().getAppName().startsWith("OpenConcerto") && gestionHoraire) {
c.gridwidth = 1;
final JPanel panelHoraires = new JPanel(new GridBagLayout());
final GridBagConstraints cH = new DefaultGridBagConstraints();
createHalfDay(panelHoraires, cH, "Matin :", "MATIN", 8, 12);
createHalfDay(panelHoraires, cH, "Après midi :", "MIDI", 13, 17);
c.gridy++;
c.gridx = 0;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 1;
c.weighty = 0;
panelHoraires.setBorder(BorderFactory.createTitledBorder("Horaires"));
this.add(panelHoraires, c);
}
if (this.accessSocieteElem != null) {
c.gridy++;
c.gridx = 0;
c.gridwidth = 4;
this.add(new JLabelBold("Accés aux sociétés"), c);
c.gridy++;
this.noCompanyLimitCheckBox = new JCheckBox("ne pas limiter l'accès à certaines sociétés");
this.add(this.noCompanyLimitCheckBox, c);
c.gridy++;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
final SQLElement companyElement = this.accessSocieteElem.getForeignElement("ID_SOCIETE_COMMON");
final List<SQLTableElement> tableElements = new ArrayList<>();
tableElements.add(new SQLTableElement(companyElement.getTable().getField("NOM")));
final RowValuesTableModel model = new RowValuesTableModel(companyElement, tableElements, companyElement.getTable().getKey(), false);
this.table = new QuickAssignPanel(companyElement, "ID", model);
this.add(this.table, c);
this.noCompanyLimitCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
UserSQLComponent.this.table.setEnabled(e.getStateChange() == ItemEvent.DESELECTED);
}
});
getView("ADMIN").addValueListener(new PropertyChangeListener() {
@Override
public void propertyChange(final PropertyChangeEvent evt) {
final boolean selected = evt.getNewValue() == Boolean.TRUE;
UserSQLComponent.this.noCompanyLimitCheckBox.setEnabled(!selected);
if (selected)
UserSQLComponent.this.noCompanyLimitCheckBox.setSelected(true);
}
});
this.noCompanyLimitCheckBox.setSelected(true);
}
this.addRequiredSQLObject(textLogin, "LOGIN");
this.addView(new SimpleRowItemView<String>(new TextValueWrapper(this.encryptedPass)) {
@Override
public void setEditable(final InteractionMode mode) {
mode.applyTo(getPassField());
mode.applyTo(getPassFieldConfirm());
}
}, "PASSWORD", REQ);
this.addSQLObject(textNom, "NOM");
this.addSQLObject(textPrenom, "PRENOM");
this.addSQLObject(textSurnom, "SURNOM");
this.getPassField().getDocument().addDocumentListener(new SimpleDocumentListener() {
@Override
public void update(final DocumentEvent e) {
updateEncrypted();
fireValidChange();
}
});
this.getPassFieldConfirm().getDocument().addDocumentListener(new SimpleDocumentListener() {
@Override
public void update(final DocumentEvent e) {
fireValidChange();
}
});
this.addViews(c);
}
protected void addViews(final GridBagConstraints c) {
}
// après midi arrivée 13:30
// __________ départ 17:53
private void createHalfDay(final JPanel panelHoraires, final GridBagConstraints cH, final String label, final String field, final int startHour, final int endHour) {
panelHoraires.add(new JLabel(label), cH);
cH.gridx++;
createTime(panelHoraires, cH, "arrivée", field + "_A", startHour);
cH.gridy++;
cH.gridx = 1;
createTime(panelHoraires, cH, "départ", field + "_D", endHour);
cH.gridy++;
cH.gridx = 0;
}
// départ 17:53
private void createTime(final JPanel panelHoraires, final GridBagConstraints cH, final String label, final String field, final int hour) {
panelHoraires.add(new JLabel(label), cH);
cH.gridx++;
final ISpinner spinHourMA = createSpinner(panelHoraires, cH, true, hour);
final ISpinner spinMinMA = createSpinner(panelHoraires, cH, false, 0);
this.addView(new SimpleRowItemView<Integer>(spinHourMA), "HEURE_" + field, null);
this.addView(new SimpleRowItemView<Integer>(spinMinMA), "MINUTE_" + field, null);
}
// 17 h or 53 min
private ISpinner createSpinner(final JPanel panelHoraires, final GridBagConstraints cH, final boolean hour, final int value) {
final ISpinnerIntegerModel modelHourMA = new ISpinnerIntegerModel(0, hour ? 23 : 59, value);
final ISpinner spinHourMA = new ISpinner(modelHourMA);
panelHoraires.add(spinHourMA.getComp(), cH);
cH.gridx++;
panelHoraires.add(new JLabel(hour ? "h" : "min"), cH);
cH.gridx++;
return spinHourMA;
}
private void updateEncrypted() {
final String pass = String.valueOf(this.getPassField().getPassword());
final String dbPass = Boolean.getBoolean(LEGACY_PASSWORDS) ? '"' + pass + '"' : pass;
this.encryptedPass.setText(Login.encodePassword(dbPass));
}
private boolean checkValidityPassword() {
final boolean b = String.valueOf(this.getPassField().getPassword()).equalsIgnoreCase(String.valueOf(this.getPassFieldConfirm().getPassword()));
this.panelWarning.setVisible(!b);
return b;
}
@Override
public synchronized ValidState getValidState() {
return super.getValidState().and(ValidState.createCached(checkValidityPassword(), TM.tr("user.passwordsDontMatch")));
}
@Override
public void select(final SQLRowAccessor row) {
// show something in the user-visible text fields, but do it before the real select
// so that this.encryptedPass (which will be updated by updateEncrypted() and thus
// have a bogus value) will be changed to its database value and thus the user can
// update any field without changing the password.
if (this.table != null) {
this.table.getModel().clearRows();
}
if (row != null) {
final String bogusPass = "bogusPass!";
this.getPassField().setText(bogusPass);
this.getPassFieldConfirm().setText(bogusPass);
// Allowed companies
if (this.accessSocieteElem != null) {
final SQLTable tableCompanyAccess = this.accessSocieteElem.getTable();
final SQLRowValues graph = new SQLRowValues(tableCompanyAccess);
graph.put("ID", null);
graph.putRowValues("ID_SOCIETE_COMMON").put("NOM", null);
final SQLRowValuesListFetcher f = new SQLRowValuesListFetcher(graph);
f.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
@Override
public SQLSelect transformChecked(final SQLSelect input) {
input.setWhere(new Where(tableCompanyAccess.getField("ID_USER_COMMON"), "=", row.getID()));
return input;
}
});
final List<SQLRowValues> companies = f.fetch();
for (final SQLRowValues r : companies) {
this.table.getModel().addRow(r.getForeign("ID_SOCIETE_COMMON").asRowValues());
}
this.noCompanyLimitCheckBox.setSelected(companies.isEmpty());
}
}
super.select(row);
}
@Override
public int insert(SQLRow order) {
int id = super.insert(order);
if (this.table != null && !noCompanyLimitCheckBox.isSelected()) {
insertCompanyAccessForUser(id);
}
return id;
}
private void insertCompanyAccessForUser(final int id) {
final SQLTable tableCompanyAccess = this.getDirectory().getElement("ACCES_SOCIETE").getTable();
final int stop = this.table.getModel().getRowCount();
for (int i = 0; i < stop; i++) {
final SQLRowValues rCompany = this.table.getModel().getRowValuesAt(i);
final SQLRowValues rAccess = new SQLRowValues(tableCompanyAccess);
rAccess.put("ID_USER_COMMON", id);
rAccess.put("ID_SOCIETE_COMMON", rCompany.getID());
try {
rAccess.commit();
} catch (final SQLException e) {
ExceptionHandler.handle("Unable to store company access", e);
}
}
}
@Override
public void update() {
super.update();
if (this.table != null) {
final SQLTable tableCompanyAccess = this.getDirectory().getElement("ACCES_SOCIETE").getTable();
String query = "DELETE FROM " + tableCompanyAccess.getSQL() + " WHERE \"ID_USER_COMMON\" = " + getSelectedID();
tableCompanyAccess.getDBSystemRoot().getDataSource().execute(query);
if (!noCompanyLimitCheckBox.isSelected()) {
insertCompanyAccessForUser(getSelectedID());
}
}
}
}
}