summaryrefslogtreecommitdiff
path: root/src/Models/User.php
blob: c92f5b31b5fe48bda29f36912d4c9747382d0f98 (plain)
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php

namespace App\Models;

use App\Database;
use App\Errors\AppException;
use App\Errors\ErrorCode;
use App\Errors\UnauthorizedError;
use App\Support\ConnectsToDatabase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class User implements ConnectsToDatabase
{
  public function __construct(
    private string $id,
    private string $name,
  )
  {}

  public static function fromDatabase(array $row): self
  {
    return new self(
      $row["id"],
      $row["name"],
    );
  }

  public static function fetch(string $id = ""): ?self
  {
    if (empty($id)) {
      throw new \InvalidArgumentException("missing user id");
    }

    return Database::getInstance()->query(
      <<<SQL
        select * from users where id=:id
      SQL,
      [
        "id" => $id,
      ]
    );
  }

  public static function fetchAll(): array
  {}

  public static function fetchWithPassword(string $id, string $password): ?self
  {
    $row = Database::getInstance()->query("select * from users where id=:id and password=:password", [
      "id" => $id,
      "password" => $password,
    ])->fetch();

    if (empty($row)) {
      return null;
    }

    return self::fromDatabase($row);
  }

  public static function fetchWithAccessToken(string $accessToken): ?self
  {
    $row = Database::getInstance()->query(<<<SQL
      select users.* from users left join tokens on tokens.user_id = users.id where tokens.access_token=:access_token
    SQL, [
      "access_token" => $accessToken,
    ])->fetch();

    if (empty($row)) {
      return null;
    }

    return self::fromDatabase($row);
  }

  public static function new(string $id, string $name): self
  {
    return new self($id, $name);
  }

  public static function authenticateWithRequest(Request $request): self
  {
    $accessToken = str_replace("Bearer ", "", $request->headers->get("authorization") ?: "");
    $user = self::fetchWithAccessToken($accessToken);

    if (empty($user)) {
      throw new UnauthorizedError();
    }

    $tokens = Tokens::fetchWithAccessToken($accessToken);

    if (empty($tokens) /*|| $tokens->isExpired()*/) {
      throw new AppException(
        ErrorCode::UNKNOWN_TOKEN,
        "Soft logged out",
        Response::HTTP_UNAUTHORIZED,
        ["soft_logout" => true],
      );
    }

    return $user;
  }

  public function insert(): bool
  {
    return !! Database::getInstance()->query(
      <<<SQL
        insert into users (id, name)
        values (:id, :name)
      SQL,
      [
        "id" => $this->id,
        "name" => $this->name,
      ]
    );
  }

  public function update(): bool
  {}

  public function delete(): bool
  {}

  public function getId(): string
  {
    return $this->id;
  }

  public function getName(): string
  {
    return $this->name;
  }

  public function fetchDevice(string $id): ?Device
  {
    return Device::fetch($id, $this->id);
  }

  /**
   * @return Device[]
   */
  public function fetchDevices(): array
  {
    return Device::fetchAll($this->id);
  }
}