/*
http-realm - Authentication Extensions to jdk.httpserver
Copyright (C) 2021 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.httpserver.auth.realm;
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 Realm, 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.
*
* @author Ulrich Hilger
* @version 1, 03.06.2021
*/
public class SimpleRealm implements Realm {
public static final String LIST_INDICATOR = "=";
public static final String ROLE_SEPARATOR = ",";
public static final String COMMENT_INDICATOR = "#";
private String name;
private final Map users;
private final Map userRoles;
/**
* Ein neues Objekt der Klasse SimpleRealm erzeugen
*/
public SimpleRealm() {
users = new HashMap<>();
userRoles = new HashMap<>();
}
/**
* Den Namen dieses Realm festlegen
* @param name Name des Realms
*/
public void setName(String name) {
this.name = name;
}
/**
* 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;
}
}
/**
* Den Namen dieses Realms ermitteln
* @return Name des Realms
*/
@Override
public String getName() {
return name;
}
}