File: auth_session_storage_impl.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (150 lines) | stat: -rw-r--r-- 5,757 bytes parent folder | download | duplicates (7)
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
148
149
150
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_ASH_COMPONENTS_OSAUTH_IMPL_AUTH_SESSION_STORAGE_IMPL_H_
#define CHROMEOS_ASH_COMPONENTS_OSAUTH_IMPL_AUTH_SESSION_STORAGE_IMPL_H_

#include <memory>
#include <optional>
#include <queue>
#include <utility>

#include "base/component_export.h"
#include "base/containers/flat_map.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/clock.h"
#include "base/time/default_clock.h"
#include "base/timer/timer.h"
#include "chromeos/ash/components/login/auth/public/auth_callbacks.h"
#include "chromeos/ash/components/osauth/public/auth_session_storage.h"
#include "chromeos/ash/components/osauth/public/common_types.h"

namespace ash {

class AuthenticationError;
class AuthPerformer;
class UserContext;
class UserDataAuthClient;

// Helper class that stores and manages lifetime of authenticated UserContext.
// Main use cases for this class are the situations where authenticated
// operations do not happen immediately after authentication, but require some
// user input, e.g. setting up additional factors during user onboarding on a
// first run, or entering authentication-related section of
// `chrome://os-settings`.
//
// When context is added to storage, storage would return a token as a
// replacement, this token can be relatively safely be passed between components
// as it does not contain any sensitive information.
//
// UserContext can be borrowed to perform authenticated operations and should be
// returned to storage as soon as operation completes.
class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_OSAUTH) AuthSessionStorageImpl
    : public AuthSessionStorage {
 public:
  explicit AuthSessionStorageImpl(
      UserDataAuthClient* user_data_auth,
      const base::Clock* clock = base::DefaultClock::GetInstance());
  ~AuthSessionStorageImpl() override;

  // AuthSessionStorage implementation:
  AuthProofToken Store(std::unique_ptr<UserContext> context) override;
  bool IsValid(const AuthProofToken& token) override;
  std::unique_ptr<UserContext> BorrowForTests(
      const base::Location& location,
      const AuthProofToken& token) override;
  void BorrowAsync(const base::Location& location,
                   const AuthProofToken& token,
                   BorrowContextCallback callback) override;
  const UserContext* Peek(const AuthProofToken& token) override;
  void Return(const AuthProofToken& token,
              std::unique_ptr<UserContext> context) override;
  void Withdraw(const AuthProofToken& token,
                BorrowContextCallback callback) override;
  void Invalidate(const AuthProofToken& token,
                  std::optional<InvalidationCallback> on_invalidated) override;
  std::unique_ptr<ScopedSessionRefresher> KeepAlive(
      const AuthProofToken& token) override;

  bool CheckHasKeepAliveForTesting(const AuthProofToken& token) const override;

 private:
  friend class ScopedSessionRefresherImpl;
  enum class TokenState {
    kOwned,         // UserContext is owned by storage
    kBorrowed,      // UserContext is currently borrowed
    kInvalidating,  // token is being invalidated
  };

  struct TokenData {
    explicit TokenData(std::unique_ptr<UserContext> context);
    ~TokenData();

    // Context associated with token
    std::unique_ptr<UserContext> context;
    TokenState state = TokenState::kOwned;

    // Code location of the last borrow operation.
    base::Location borrow_location;

    // Data required to invalidate context upon return, if invalidation was
    // requested while context is borrowed.
    bool invalidate_on_return = false;

    std::queue<InvalidationCallback> invalidation_queue;
    std::optional<BorrowContextCallback> withdraw_callback;
    std::queue<std::pair<base::Location, BorrowContextCallback>> borrow_queue;

    // Timer to perform next action (extending or invalidating session).
    std::unique_ptr<base::OneShotTimer> next_action_timer_;

    // Number of entities that requested to keep session alive.
    int keep_alive_counter = 0;
  };

  std::unique_ptr<UserContext> Borrow(const base::Location& location,
                                      const AuthProofToken& token);
  void OnSessionInvalidated(const AuthProofToken& token,
                            std::unique_ptr<UserContext> context,
                            std::optional<AuthenticationError> error);

  void HandleSessionRefresh(const AuthProofToken& token);
  void ExtendAuthSession(const AuthProofToken& token);
  void OnExtendAuthSession(const AuthProofToken& token,
                           std::unique_ptr<UserContext> context,
                           std::optional<AuthenticationError> error);

  // Internal API for ScopedSessionRefresher.
  void IncreaseKeepAliveCounter(const AuthProofToken& token);
  void DecreaseKeepAliveCounter(const AuthProofToken& token);

  // Stored data for currently active tokens.
  base::flat_map<AuthProofToken, std::unique_ptr<TokenData>> tokens_;

  std::unique_ptr<AuthPerformer> auth_performer_;

  const raw_ptr<const base::Clock> clock_;

  base::WeakPtrFactory<AuthSessionStorageImpl> weak_factory_{this};
};

class ScopedSessionRefresherImpl : public ScopedSessionRefresher {
 public:
  ~ScopedSessionRefresherImpl() override;

 private:
  friend class AuthSessionStorageImpl;

  ScopedSessionRefresherImpl(base::WeakPtr<AuthSessionStorageImpl> storage,
                             const AuthProofToken& token);

  base::WeakPtr<AuthSessionStorageImpl> storage_;
  AuthProofToken token_;
};

}  // namespace ash

#endif  // CHROMEOS_ASH_COMPONENTS_OSAUTH_IMPL_AUTH_SESSION_STORAGE_IMPL_H_