OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 73 | Rev 93 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.sql.users;
15
 
16
import org.openconcerto.sql.Configuration;
73 ilm 17
import org.openconcerto.sql.TM;
17 ilm 18
import org.openconcerto.sql.element.BaseSQLComponent;
19
import org.openconcerto.sql.element.ConfSQLElement;
20
import org.openconcerto.sql.element.SQLComponent;
80 ilm 21
import org.openconcerto.sql.element.SQLElement;
17 ilm 22
import org.openconcerto.sql.model.SQLRow;
23
import org.openconcerto.sql.model.SQLRowAccessor;
80 ilm 24
import org.openconcerto.sql.model.SQLRowValues;
25
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
26
import org.openconcerto.sql.model.SQLSelect;
27
import org.openconcerto.sql.model.SQLTable;
28
import org.openconcerto.sql.model.Where;
17 ilm 29
import org.openconcerto.sql.request.ComboSQLRequest;
30
import org.openconcerto.sql.sqlobject.itemview.SimpleRowItemView;
31
import org.openconcerto.sql.ui.Login;
80 ilm 32
import org.openconcerto.sql.view.QuickAssignPanel;
33
import org.openconcerto.sql.view.list.RowValuesTableModel;
34
import org.openconcerto.sql.view.list.SQLTableElement;
17 ilm 35
import org.openconcerto.ui.DefaultGridBagConstraints;
36
import org.openconcerto.ui.ISpinner;
37
import org.openconcerto.ui.ISpinnerIntegerModel;
80 ilm 38
import org.openconcerto.ui.JLabelBold;
67 ilm 39
import org.openconcerto.ui.valuewrapper.TextValueWrapper;
17 ilm 40
import org.openconcerto.ui.warning.JLabelWarning;
41
import org.openconcerto.utils.CollectionMap;
80 ilm 42
import org.openconcerto.utils.ExceptionHandler;
43
import org.openconcerto.utils.cc.ITransformer;
21 ilm 44
import org.openconcerto.utils.checks.ValidState;
73 ilm 45
import org.openconcerto.utils.i18n.I18nUtils;
17 ilm 46
import org.openconcerto.utils.text.SimpleDocumentListener;
47
 
48
import java.awt.GridBagConstraints;
49
import java.awt.GridBagLayout;
50
import java.awt.Insets;
80 ilm 51
import java.awt.event.ItemEvent;
52
import java.awt.event.ItemListener;
53
import java.beans.PropertyChangeEvent;
54
import java.beans.PropertyChangeListener;
55
import java.sql.SQLException;
17 ilm 56
import java.util.ArrayList;
57
import java.util.List;
58
 
59
import javax.swing.BorderFactory;
60
import javax.swing.JCheckBox;
61
import javax.swing.JLabel;
62
import javax.swing.JPanel;
63
import javax.swing.JPasswordField;
64
import javax.swing.JTextField;
65
import javax.swing.SwingConstants;
66
import javax.swing.event.DocumentEvent;
67
 
68
// FIXME Login user unique ?
69
public class UserCommonSQLElement extends ConfSQLElement {
70
 
71
    /**
72
     * Set this system property to "true" if this should generate old style passwords.
73
     */
74
    public static final String LEGACY_PASSWORDS = "org.openconcerto.sql.legacyPasswords";
75
 
76
    public UserCommonSQLElement() {
73 ilm 77
        super("USER_COMMON");
78
        this.setL18nPackageName(I18nUtils.getPackageName(TM.class));
17 ilm 79
    }
80
 
81
    @Override
82
    protected List<String> getListFields() {
83
        final List<String> l = new ArrayList<String>();
84
        l.add("NOM");
85
        l.add("PRENOM");
86
        l.add("LOGIN");
87
        return l;
88
    }
89
 
90
    @Override
91
    protected List<String> getComboFields() {
92
        final List<String> l = new ArrayList<String>();
93
        l.add("NOM");
94
        l.add("PRENOM");
95
        return l;
96
    }
97
 
98
    @Override
61 ilm 99
    protected ComboSQLRequest createComboRequest() {
100
        final ComboSQLRequest res = super.createComboRequest();
17 ilm 101
        res.setFieldSeparator(" ");
102
        return res;
103
    }
104
 
105
    @Override
106
    public CollectionMap<String, String> getShowAs() {
107
        return CollectionMap.singleton(null, "PRENOM", "NOM");
108
    }
109
 
110
    /*
111
     * (non-Javadoc)
112
     *
113
     * @see org.openconcerto.devis.SQLElement#getComponent()
114
     */
115
    @Override
116
    public SQLComponent createComponent() {
117
        return new BaseSQLComponent(this) {
118
 
119
            private JPasswordField passField, passFieldConfirm;
120
            private JPanel panelWarning;
80 ilm 121
            private final SQLElement accessSocieteElem;
122
            private QuickAssignPanel table;
67 ilm 123
            // TODO transform into real SQLRowItemView
17 ilm 124
            private final JTextField encryptedPass = new JTextField();
80 ilm 125
            private JCheckBox noCompanyLimitCheckBox;
17 ilm 126
 
80 ilm 127
            {
128
                final SQLTable t = getTable().getDBSystemRoot().getGraph().findReferentTable(getTable(), "ACCES_SOCIETE");
129
                this.accessSocieteElem = t == null ? null : getDirectory().getElement(t);
130
            }
131
 
67 ilm 132
            protected final JPasswordField getPassField() {
133
                return this.passField;
134
            }
135
 
136
            protected final JPasswordField getPassFieldConfirm() {
137
                return this.passFieldConfirm;
138
            }
139
 
17 ilm 140
            @Override
141
            public void addViews() {
142
                final GridBagConstraints c = new GridBagConstraints();
143
                c.insets = new Insets(0, 0, 0, 0);
144
                c.gridx = 0;
145
                c.gridy = 0;
146
                c.weightx = 0;
147
                c.weighty = 0;
148
                c.fill = GridBagConstraints.HORIZONTAL;
149
                c.anchor = GridBagConstraints.WEST;
150
 
151
                this.panelWarning = new JPanel(new GridBagLayout());
80 ilm 152
                this.panelWarning.setBorder(BorderFactory.createEmptyBorder());
17 ilm 153
                final JLabelWarning labelWarning = new JLabelWarning();
154
                // labelWarning.setBorder(null);
155
                this.panelWarning.add(labelWarning, c);
73 ilm 156
                final JLabel labelTextWarning = new JLabel(TM.tr("user.passwordsDontMatch.short"));
17 ilm 157
                // labelTextWarning.setBorder(null);
158
                c.gridx++;
159
                this.panelWarning.add(labelTextWarning, c);
160
 
161
                final GridBagLayout layout = new GridBagLayout();
162
                this.setLayout(layout);
163
 
164
                // Login
165
                c.gridx = 0;
166
                c.insets = new Insets(2, 2, 1, 2);
167
                final JLabel labelLogin = new JLabel(getLabelFor("LOGIN"));
168
                labelLogin.setHorizontalAlignment(SwingConstants.RIGHT);
169
                this.add(labelLogin, c);
170
                final JTextField textLogin = new JTextField();
171
                c.gridx++;
172
                DefaultGridBagConstraints.lockMinimumSize(textLogin);
173
                c.weightx = 1;
174
                this.add(textLogin, c);
175
 
176
                // Warning
177
                c.gridwidth = GridBagConstraints.REMAINDER;
178
                c.gridx++;
179
                c.insets = new Insets(0, 0, 0, 0);
180
                this.add(this.panelWarning, c);
181
                this.panelWarning.setVisible(false);
182
 
183
                // Pass
184
                c.gridy++;
185
                c.gridwidth = 1;
186
                c.gridx = 0;
187
                c.weightx = 0;
188
                c.insets = new Insets(2, 2, 1, 2);
189
                final JLabel labelPass = new JLabel(getLabelFor("PASSWORD"));
190
                labelPass.setHorizontalAlignment(SwingConstants.RIGHT);
191
                this.add(labelPass, c);
192
                // JTextField textPass = new JTextField();
193
                this.passField = new JPasswordField(15);
194
                c.gridx++;
195
                c.weightx = 1;
67 ilm 196
                DefaultGridBagConstraints.lockMinimumSize(this.getPassField());
197
                this.add(this.getPassField(), c);
17 ilm 198
 
199
                // Confirmation password
200
                c.gridx++;
201
                c.weightx = 0;
73 ilm 202
                final JLabel labelConfirmationPass = new JLabel(getLabelFor("PASSWORD_CONFIRM"));
17 ilm 203
                labelConfirmationPass.setHorizontalAlignment(SwingConstants.RIGHT);
204
                this.add(labelConfirmationPass, c);
205
                this.passFieldConfirm = new JPasswordField(15);
206
                c.gridx++;
207
                c.weightx = 1;
67 ilm 208
                DefaultGridBagConstraints.lockMinimumSize(this.getPassFieldConfirm());
209
                this.add(this.getPassFieldConfirm(), c);
17 ilm 210
 
211
                // Nom
212
                c.gridx = 0;
213
                c.gridy++;
214
                c.weightx = 0;
215
                final JLabel labelNom = new JLabel(getLabelFor("NOM"));
216
                labelNom.setHorizontalAlignment(SwingConstants.RIGHT);
217
                this.add(labelNom, c);
218
                final JTextField textNom = new JTextField();
219
                c.gridx++;
220
                c.weightx = 1;
221
                this.add(textNom, c);
222
 
223
                // Prenom
224
                c.gridx++;
225
                c.weightx = 0;
226
                final JLabel labelPrenom = new JLabel(getLabelFor("PRENOM"));
227
                labelPrenom.setHorizontalAlignment(SwingConstants.RIGHT);
228
                this.add(labelPrenom, c);
229
                final JTextField textPrenom = new JTextField();
230
                c.gridx++;
231
                c.weightx = 1;
232
                this.add(textPrenom, c);
233
 
234
                // Surnom
235
                c.gridx = 0;
236
                c.gridy++;
237
                c.weightx = 0;
238
                final JLabel labelSurnom = new JLabel(getLabelFor("SURNOM"));
239
                labelSurnom.setHorizontalAlignment(SwingConstants.RIGHT);
240
                this.add(labelSurnom, c);
241
                final JTextField textSurnom = new JTextField();
242
                c.gridx++;
243
                c.weightx = 1;
244
                this.add(textSurnom, c);
245
 
246
                if (this.getTable().contains("ADMIN")) {
80 ilm 247
                    final JCheckBox checkAdmin = new JCheckBox(getLabelFor("ADMIN"));
17 ilm 248
                    c.gridx++;
249
                    c.gridwidth = GridBagConstraints.REMAINDER;
250
                    c.weightx = 0;
251
                    this.add(checkAdmin, c);
252
                    this.addView(checkAdmin, "ADMIN");
253
                }
254
 
255
                c.gridy++;
256
                c.gridwidth = 1;
257
                c.gridx = 0;
258
                c.weightx = 0;
259
 
260
                if (getTable().contains("MAIL")) {
261
                    final JLabel labelMail = new JLabel(getLabelFor("MAIL"));
262
                    labelMail.setHorizontalAlignment(SwingConstants.RIGHT);
263
                    c.anchor = GridBagConstraints.NORTHWEST;
264
                    this.add(labelMail, c);
265
                    c.gridx++;
266
                    final JTextField textMail = new JTextField();
267
                    c.gridwidth = GridBagConstraints.REMAINDER;
268
                    c.weightx = 1;
269
 
270
                    this.add(textMail, c);
271
                    this.addView(textMail, "MAIL");
272
                }
273
 
274
                boolean gestionHoraire = false;
275
                if (Configuration.getInstance().getAppName().startsWith("OpenConcerto") && gestionHoraire) {
276
 
277
                    c.gridwidth = 1;
278
                    JPanel panelHoraires = new JPanel(new GridBagLayout());
279
                    GridBagConstraints cH = new DefaultGridBagConstraints();
280
 
281
                    createHalfDay(panelHoraires, cH, "Matin :", "MATIN", 8, 12);
282
                    createHalfDay(panelHoraires, cH, "Après midi :", "MIDI", 13, 17);
283
 
284
                    c.gridy++;
285
                    c.gridx = 0;
286
                    c.gridwidth = GridBagConstraints.REMAINDER;
287
                    c.weightx = 1;
288
                    c.weighty = 0;
289
                    panelHoraires.setBorder(BorderFactory.createTitledBorder("Horaires"));
290
                    this.add(panelHoraires, c);
80 ilm 291
                }
17 ilm 292
 
80 ilm 293
                if (this.accessSocieteElem != null) {
17 ilm 294
                    c.gridy++;
80 ilm 295
                    c.gridx = 0;
296
                    c.gridwidth = 4;
297
 
298
                    this.add(new JLabelBold("Accés aux sociétés"), c);
299
                    c.gridy++;
300
                    noCompanyLimitCheckBox = new JCheckBox("ne pas limiter l'accès à certaines sociétés");
301
                    this.add(noCompanyLimitCheckBox, c);
302
 
303
                    c.gridy++;
17 ilm 304
                    c.weighty = 1;
80 ilm 305
                    c.fill = GridBagConstraints.BOTH;
306
                    final SQLElement companyElement = this.accessSocieteElem.getForeignElement("ID_SOCIETE_COMMON");
307
                    final List<SQLTableElement> tableElements = new ArrayList<SQLTableElement>();
308
                    tableElements.add(new SQLTableElement(companyElement.getTable().getField("NOM")));
309
                    final RowValuesTableModel model = new RowValuesTableModel(companyElement, tableElements, companyElement.getTable().getKey(), false);
310
                    this.table = new QuickAssignPanel(companyElement, "ID", model);
17 ilm 311
                    this.add(this.table, c);
80 ilm 312
 
313
                    noCompanyLimitCheckBox.addItemListener(new ItemListener() {
314
                        @Override
315
                        public void itemStateChanged(ItemEvent e) {
316
                            table.setEnabled(e.getStateChange() == ItemEvent.DESELECTED);
317
                        }
318
                    });
319
                    getView("ADMIN").addValueListener(new PropertyChangeListener() {
320
                        @Override
321
                        public void propertyChange(PropertyChangeEvent evt) {
322
                            final boolean selected = evt.getNewValue() == Boolean.TRUE;
323
                            noCompanyLimitCheckBox.setEnabled(!selected);
324
                            if (selected)
325
                                noCompanyLimitCheckBox.setSelected(true);
326
                        }
327
                    });
328
                    noCompanyLimitCheckBox.setSelected(true);
17 ilm 329
                }
330
 
331
                this.addRequiredSQLObject(textLogin, "LOGIN");
67 ilm 332
                this.addView(new SimpleRowItemView<String>(new TextValueWrapper(this.encryptedPass)) {
333
                    @Override
334
                    public void setEditable(boolean b) {
335
                        getPassField().setEnabled(b);
336
                        getPassFieldConfirm().setEnabled(b);
337
                    };
338
                }, "PASSWORD", REQ);
17 ilm 339
                this.addSQLObject(textNom, "NOM");
340
                this.addSQLObject(textPrenom, "PRENOM");
341
                this.addSQLObject(textSurnom, "SURNOM");
342
 
67 ilm 343
                this.getPassField().getDocument().addDocumentListener(new SimpleDocumentListener() {
17 ilm 344
                    @Override
345
                    public void update(DocumentEvent e) {
346
                        updateEncrypted();
347
                        fireValidChange();
348
                    }
349
                });
67 ilm 350
                this.getPassFieldConfirm().getDocument().addDocumentListener(new SimpleDocumentListener() {
17 ilm 351
                    @Override
352
                    public void update(DocumentEvent e) {
353
                        fireValidChange();
354
                    }
355
                });
356
            }
357
 
358
            // après midi arrivée 13:30
359
            // __________ départ 17:53
360
            private void createHalfDay(JPanel panelHoraires, GridBagConstraints cH, String label, String field, int startHour, int endHour) {
361
                panelHoraires.add(new JLabel(label), cH);
362
                cH.gridx++;
363
                createTime(panelHoraires, cH, "arrivée", field + "_A", startHour);
364
                cH.gridy++;
365
                cH.gridx = 1;
366
                createTime(panelHoraires, cH, "départ", field + "_D", endHour);
367
                cH.gridy++;
368
                cH.gridx = 0;
369
            }
370
 
371
            // départ 17:53
372
            private void createTime(JPanel panelHoraires, GridBagConstraints cH, String label, String field, int hour) {
373
                panelHoraires.add(new JLabel(label), cH);
374
                cH.gridx++;
375
 
376
                final ISpinner spinHourMA = createSpinner(panelHoraires, cH, true, hour);
377
                final ISpinner spinMinMA = createSpinner(panelHoraires, cH, false, 0);
378
 
379
                this.addView(new SimpleRowItemView<Integer>(spinHourMA), "HEURE_" + field, null);
380
                this.addView(new SimpleRowItemView<Integer>(spinMinMA), "MINUTE_" + field, null);
381
            }
382
 
383
            // 17 h or 53 min
384
            private ISpinner createSpinner(JPanel panelHoraires, GridBagConstraints cH, final boolean hour, int value) {
385
                ISpinnerIntegerModel modelHourMA = new ISpinnerIntegerModel(0, hour ? 23 : 59, value);
386
                ISpinner spinHourMA = new ISpinner(modelHourMA);
387
                panelHoraires.add(spinHourMA.getComp(), cH);
388
                cH.gridx++;
389
                panelHoraires.add(new JLabel(hour ? "h" : "min"), cH);
390
                cH.gridx++;
391
                return spinHourMA;
392
            }
393
 
394
            private void updateEncrypted() {
67 ilm 395
                final String pass = String.valueOf(this.getPassField().getPassword());
17 ilm 396
                final String dbPass = Boolean.getBoolean(LEGACY_PASSWORDS) ? '"' + pass + '"' : pass;
397
                this.encryptedPass.setText(Login.encodePassword(dbPass));
398
            }
399
 
400
            private boolean checkValidityPassword() {
67 ilm 401
                final boolean b = String.valueOf(this.getPassField().getPassword()).equalsIgnoreCase(String.valueOf(this.getPassFieldConfirm().getPassword()));
17 ilm 402
                this.panelWarning.setVisible(!b);
403
                return b;
404
            }
405
 
406
            @Override
21 ilm 407
            public synchronized ValidState getValidState() {
73 ilm 408
                return super.getValidState().and(ValidState.createCached(checkValidityPassword(), TM.tr("user.passwordsDontMatch")));
17 ilm 409
            }
410
 
411
            @Override
412
            public void select(final SQLRowAccessor row) {
413
                // show something in the user-visible text fields, but do it before the real select
414
                // so that this.encryptedPass (which will be updated by updateEncrypted() and thus
415
                // have a bogus value) will be changed to its database value and thus the user can
416
                // update any field without changing the password.
80 ilm 417
                if (table != null) {
418
                    table.getModel().clearRows();
419
                }
17 ilm 420
                if (row != null) {
421
                    final String bogusPass = "bogusPass!";
67 ilm 422
                    this.getPassField().setText(bogusPass);
423
                    this.getPassFieldConfirm().setText(bogusPass);
80 ilm 424
                    // Allowed companies
425
                    if (this.accessSocieteElem != null) {
426
                        final SQLTable tableCompanyAccess = this.accessSocieteElem.getTable();
427
                        SQLRowValues graph = new SQLRowValues(tableCompanyAccess);
428
                        graph.put("ID", null);
429
                        graph.putRowValues("ID_SOCIETE_COMMON").put("NOM", null);
430
                        SQLRowValuesListFetcher f = new SQLRowValuesListFetcher(graph);
431
                        f.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
432
                            @Override
433
                            public SQLSelect transformChecked(SQLSelect input) {
434
                                input.setWhere(new Where(tableCompanyAccess.getField("ID_USER_COMMON"), "=", row.getID()));
435
                                return input;
436
                            }
437
                        });
438
                        List<SQLRowValues> companies = f.fetch();
439
 
440
                        for (SQLRowValues r : companies) {
441
                            table.getModel().addRow(r.getForeign("ID_SOCIETE_COMMON").asRowValues());
442
                        }
443
                        noCompanyLimitCheckBox.setSelected(companies.isEmpty());
17 ilm 444
                    }
445
                }
446
                super.select(row);
447
            }
448
 
449
            @Override
450
            public int insert(SQLRow order) {
451
                int id = super.insert(order);
80 ilm 452
                if (this.table != null && !noCompanyLimitCheckBox.isSelected()) {
453
                    insertCompanyAccessForUser(id);
17 ilm 454
                }
455
                return id;
456
            }
457
 
80 ilm 458
            private void insertCompanyAccessForUser(int id) {
459
                final SQLTable tableCompanyAccess = this.getDirectory().getElement("ACCES_SOCIETE").getTable();
460
                int stop = table.getModel().getRowCount();
461
                for (int i = 0; i < stop; i++) {
462
                    SQLRowValues rCompany = table.getModel().getRowValuesAt(i);
463
                    SQLRowValues rAccess = new SQLRowValues(tableCompanyAccess);
464
                    rAccess.put("ID_USER_COMMON", id);
465
                    rAccess.put("ID_SOCIETE_COMMON", rCompany.getID());
466
                    try {
467
                        rAccess.commit();
468
                    } catch (SQLException e) {
469
                        ExceptionHandler.handle("Unable to store company access", e);
470
                    }
471
                }
472
            }
473
 
17 ilm 474
            @Override
475
            public void update() {
476
                super.update();
477
                if (this.table != null) {
80 ilm 478
                    final SQLTable tableCompanyAccess = this.getDirectory().getElement("ACCES_SOCIETE").getTable();
479
                    String query = "DELETE FROM " + tableCompanyAccess.getSQL() + " WHERE \"ID_USER_COMMON\" = " + getSelectedID();
480
                    tableCompanyAccess.getDBSystemRoot().getDataSource().execute(query);
481
                    if (!noCompanyLimitCheckBox.isSelected()) {
482
                        insertCompanyAccessForUser(getSelectedID());
483
                    }
17 ilm 484
                }
485
            }
486
        };
487
    }
488
}