/* neon-auth - Authentication Extensions to Neon Copyright (C) 2024 Ulrich Hilger This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package de.uhilger.neon.auth; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Eine einfache Implementierung der Schnittstelle Directory, die * Benutzerinformationen aus einer Datei liest. Die Datei ist dabei * wie folgt aufgebaut. * * test=test,testRolle * ulrich=ulrich,testRolle,andereRolle * * Der erste Eintrag nach dem Gleichheitszeichen ist das Passwort, die restlichen * Eintraege sind Rollen. * * Unschoen und daher nur fuer nicht kritische Anwendungen oder fuer Tests * geeignet: Die Kennworte sind nach dem Lesen der Benutzerddaten * dann in einer Map im RAM. Sie werden dort zwar nur verglichen mit * einem Kennwort-Parameter, der ueber isValid hereinkommt, es ist aber dennoch * unschoen, dass die Kennworte im RAM liegen. * * @author Ulrich Hilger * @version 1, 03.06.2021 */ public class SimpleDirectory implements Directory { public static final String LIST_INDICATOR = "="; public static final String ROLE_SEPARATOR = ","; public static final String COMMENT_INDICATOR = "#"; private final Map users; private final Map userRoles; /** * Ein neues Objekt der Klasse SimpleRealm erzeugen */ public SimpleDirectory() { users = new HashMap<>(); userRoles = new HashMap<>(); } /** * Nutzerinformationen aus einer Datei lesen * @param file die Datei mit Nutzerinformationen * @throws IOException */ public void readFromFile(File file) throws IOException { BufferedReader r = new BufferedReader(new FileReader(file)); String line = r.readLine(); while(line != null) { parse(line); line = r.readLine(); } r.close(); } /** * Eine Zeile aus der Datei mit Nutzerinformationen verarbeiten * @param line die Zeile, die verarbeitet werden soll */ private void parse(String line) { if(!line.startsWith(COMMENT_INDICATOR)) { String[] teile = line.split(LIST_INDICATOR); String[] rollen = teile[1].split(ROLE_SEPARATOR); String userId = teile[0]; User user = new User(); user.setName(userId); user.setPassword(rollen[0]); try { Encoder encoder = new Encoder(); String hex = encoder.bytesToHex(encoder.encode(rollen[0])); //logger.fine(hex); } catch (NoSuchAlgorithmException ex) { //logger.log(Level.SEVERE, null, ex); } ArrayList rollenListe = new ArrayList(); for(int i = 1; i < rollen.length; i++) { rollenListe.add(rollen[i]); } users.put(userId, user); userRoles.put(userId, rollenListe); } } /* ------------ Realm implementation -------------- */ /** * Uberpruefen, ob die Benutzerkennung und das Kennwort gueltig sind. * * @param userId der Benutzer * @param password das Kennwort des Benutzers * @return true, wenn die Angaben stimmen, false wenn nicht */ @Override public boolean isValid(String userId, String password) { Object o = users.get(userId); if(o instanceof User) { User user = (User) o; return user.getPassword().equals(password); } else { return false; } } /** * Pruefen, ob ein Benutzer eine Rolle hat * * @param userId der Benutzer * @param roleId die Kennung der Rolle * @return true, wenn der Benutzer die Rolle hat, false wenn nicht */ @Override public boolean hasRole(String userId, String roleId) { Object o = userRoles.get(userId); if(o instanceof List) { List roles = (List) o; return roles.contains(roleId); } else { return false; } } }