aboutsummaryrefslogtreecommitdiff
path: root/src/org/slcl/core/Login.java
blob: e52a01a16a32afa1c2322e7403e5733d677bd641 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
 * 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 <https://www.gnu.org/licenses/>.
 */

package org.slcl.core;

import org.slcl.core.Connection;
import java.io.OutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.Map;

public final class Login {
    public String login(final boolean https, final String url,
        final String username, final String password) throws IOException
    {
        final Connection conn = new Connection(https, url + "/login");
        final HttpURLConnection c = conn.getConnection();

        c.setRequestMethod("POST");
        c.setInstanceFollowRedirects(false);
        c.setReadTimeout(5000);

        final OutputStream os = c.getOutputStream();
        final String data = "username=" + username + "&password=" + password;

        os.write(data.getBytes());

        final int code = c.getResponseCode();

        switch (code)
        {
            case HttpURLConnection.HTTP_FORBIDDEN:
                throw new IOException("Forbidden");

            case HttpURLConnection.HTTP_UNAUTHORIZED:
                throw new IOException("Unauthorized");

            case HttpURLConnection.HTTP_SEE_OTHER:
            {
                final Map<String,List<String>> headers = c.getHeaderFields();
                final List<String> cookies = headers.get("Set-Cookie");
                final List<String> locations = headers.get("Location");

                if (locations == null) {
                    throw new IOException("Expected Location header");
                } else if (locations.size() != 1) {
                    throw new IOException("Expected only 1 Location header");
                }

                final String location = locations.toArray(new String[0])[0],
                    exp_location = "/user/";

                if (!location.equals(exp_location)) {
                    throw new IOException("Expected redirection to "
                        + exp_location + ", got \"" + location + "\"");
                }

                if (cookies != null) {
                    if (cookies.size() != 1) {
                        throw new IOException("Expected only 1 cookie");
                    }

                    return cookies.toArray(new String[0])[0];
                } else {
                    throw new IOException("No Cookie found");
                }
            }

            default:
                throw new IOException("Unexpected HTTP status " + code);
        }
    }
}