/* * slcl-android, an Android frontend for slcl * Copyright (C) 2023-2024 Xavier Del Campo Romero * * 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 org.slcl.core; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.IOException; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; public final class Cookie { final String username, cookie; final CookieDate date; private final class Results { final String username, cookie; final CookieDate date; Results(String username, String cookie, final CookieDate date) { this.username = username; this.cookie = cookie; this.date = date; } } public Cookie(final File f) throws IOException { final FileInputStream fis = new FileInputStream(f); final InputStreamReader ir = new InputStreamReader(fis); final BufferedReader r = new BufferedReader(ir); final String data = r.readLine(); if (data == null) { fis.close(); throw new IOException("empty file"); } final Results res = from_data(null, data); username = res.username; cookie = res.cookie; date = res.date; fis.close(); } private final class CookieDate { final private String FMT = "EEE, dd MMM yyyy HH:mm:ss z"; final DateTime date; public CookieDate(final String[] tokens) throws IOException { for (int i = 1; i < tokens.length; i++) { final String[] date_tokens = tokens[i].split("="); if (date_tokens.length != 2) { continue; } final String header = date_tokens[0].trim(); if (!header.equalsIgnoreCase("Expires")) { continue; } final DateTimeFormatter fmt = DateTimeFormat.forPattern(FMT); try { final DateTime dt = fmt.parseDateTime(date_tokens[1]); date = dt; return; } catch (final IllegalArgumentException e) { throw new IOException(e.getMessage()); } catch (final UnsupportedOperationException e) { throw new IOException(e.getMessage()); } } throw new IOException("missing expiration date"); } public String toString() { return date.toString(FMT); } public DateTime getDate() { return date; } } private Results from_data(final String exp_username, final String data) throws IOException { final int sep = data.indexOf('='); if (sep <= 0) { throw new IOException("expected key=value format"); } final String username = data.substring(0, sep); if (exp_username != null && !username.equals(exp_username)) { throw new IOException("wrong username"); } final String[] tokens = data.substring(sep + 1).split(";"); if (tokens.length < 2) { throw new IOException("expected at least two tokens"); } return new Results(username, tokens[0], new CookieDate(tokens)); } public Cookie(final String exp_username, final String data) throws IOException { final Results r = from_data(exp_username, data); username = r.username; cookie = r.cookie; date = r.date; } public void store(final File f) throws IOException { final FileOutputStream fos = new FileOutputStream(f); final String datestr = "Expires=" + date.toString(); fos.write(cookie.getBytes()); fos.write(';'); fos.write(datestr.getBytes()); fos.write('\n'); fos.close(); } public String getCookie() { return cookie; } }