• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender / 1332919177

14 Jun 2024 02:53PM UTC coverage: 75.535% (+0.001%) from 75.534%
1332919177

push

gitlab-ci

web-flow
Merge pull request #1637 from kacf/direct_linking

feat: Implement support for compiling without DBus.

47 of 60 new or added lines in 2 files covered. (78.33%)

3 existing lines in 3 files now uncovered.

7058 of 9344 relevant lines covered (75.54%)

11667.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.81
/src/api/auth/auth.cpp
1
// Copyright 2023 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
#include <api/auth.hpp>
16

17
#include <common/log.hpp>
18

19
namespace mender {
20
namespace api {
21
namespace auth {
22

23
namespace mlog = mender::common::log;
24

25
using namespace std;
26

27
const AuthenticatorErrorCategoryClass AuthenticatorErrorCategory;
28

29
const char *AuthenticatorErrorCategoryClass::name() const noexcept {
×
30
        return "AuthenticatorErrorCategory";
×
31
}
32

33
string AuthenticatorErrorCategoryClass::message(int code) const {
×
34
        switch (code) {
×
35
        case NoError:
36
                return "Success";
×
37
        case APIError:
38
                return "API error";
×
39
        case UnauthorizedError:
40
                return "Unauthorized error";
×
41
        case AuthenticationError:
42
                return "Authentication error";
×
43
        default:
44
                return "Unknown";
×
45
        }
46
}
47

48
error::Error MakeError(AuthenticatorErrorCode code, const string &msg) {
3✔
49
        return error::Error(error_condition(code, AuthenticatorErrorCategory), msg);
5✔
50
}
51

52
void Authenticator::ExpireToken() {
28✔
53
        if (!token_fetch_in_progress_) {
28✔
54
                RequestNewToken();
56✔
55
        }
56
}
28✔
57

58
error::Error Authenticator::WithToken(AuthenticatedAction action) {
22✔
59
        pending_actions_.push_back(action);
22✔
60

61
        auto err = StartWatchingTokenSignal();
22✔
62
        if (err != error::NoError) {
22✔
63
                // Should never fail. We rely on the signal heavily so let's fail
64
                // hard if it does.
65
                return err;
1✔
66
        }
67

68
        if (token_fetch_in_progress_) {
21✔
69
                // Already waiting for a new token.
70
                return error::NoError;
6✔
71
        }
72
        // else => should fetch the token, cache it and call all pending actions
73

74
        err = GetJwtToken();
15✔
75
        if (err != error::NoError) {
15✔
76
                // No token and failed to try to get one (should never happen).
NEW
77
                ExpectedAuthData ex_auth_data = expected::unexpected(err);
×
NEW
78
                PostPendingActions(ex_auth_data);
×
NEW
79
                return err;
×
80
        }
81
        // else record that token is already being fetched (by GetJwtToken()).
82
        token_fetch_in_progress_ = true;
15✔
83

84
        return error::NoError;
15✔
85
}
86

87
void Authenticator::PostPendingActions(const ExpectedAuthData &ex_auth_data) {
43✔
88
        token_fetch_in_progress_ = false;
43✔
89
        for (auto action : pending_actions_) {
64✔
90
                loop_.Post([action, ex_auth_data]() { action(ex_auth_data); });
105✔
91
        }
92
        pending_actions_.clear();
43✔
93
}
43✔
94

95
error::Error Authenticator::RequestNewToken() {
29✔
96
        auto err = FetchJwtToken();
29✔
97
        if (err != error::NoError) {
29✔
98
                mlog::Error("Failed to request new token fetching: " + err.String());
46✔
99
                ExpectedAuthData ex_auth_data = expected::unexpected(err);
23✔
100
                PostPendingActions(ex_auth_data);
23✔
101
                return err;
23✔
102
        }
103

104
        token_fetch_in_progress_ = true;
6✔
105

106
        // Make sure we don't wait for the token forever.
107
        auth_timeout_timer_.AsyncWait(auth_timeout_, [this](error::Error err) {
6✔
108
                if (err.code == make_error_condition(errc::operation_canceled)) {
6✔
109
                        return;
110
                } else if (err == error::NoError) {
2✔
111
                        mlog::Warning("Timed-out waiting for a new token");
4✔
112
                        ExpectedAuthData ex_auth_data = expected::unexpected(
2✔
113
                                MakeError(AuthenticationError, "Timed-out waiting for a new token"));
6✔
114
                        PostPendingActions(ex_auth_data);
2✔
115
                } else {
116
                        // should never happen
117
                        assert(false);
118
                        mlog::Error("Authentication timer error: " + err.String());
×
119

120
                        // In case it did happen, run the stacked up actions and unset the
121
                        // in_progress_ flag or things may got stuck.
122
                        ExpectedAuthData ex_auth_data = expected::unexpected(err);
×
123
                        PostPendingActions(ex_auth_data);
×
124
                }
125
        });
×
126
        return error::NoError;
6✔
127
}
128

129
void Authenticator::HandleReceivedToken(
19✔
130
        common::ExpectedStringPair ex_auth_dbus_data, NoTokenAction no_token) {
131
        auth_timeout_timer_.Cancel();
19✔
132
        ExpectedAuthData ex_auth_data;
133
        if (!ex_auth_dbus_data) {
19✔
134
                mlog::Error("Error receiving the JWT token: " + ex_auth_dbus_data.error().String());
2✔
135
                ex_auth_data = expected::unexpected(ex_auth_dbus_data.error());
2✔
136
        } else {
137
                auto &token = ex_auth_dbus_data.value().first;
18✔
138
                auto &server_url = ex_auth_dbus_data.value().second;
18✔
139

140
                mlog::Debug("Got new authentication token for server " + server_url);
18✔
141

142
                AuthData auth_data {server_url, token};
35✔
143
                ex_auth_data = ExpectedAuthData(std::move(auth_data));
18✔
144

145
                if (no_token == NoTokenAction::RequestNew and (token == "" or server_url == "")) {
18✔
146
                        RequestNewToken();
1✔
147
                        return;
1✔
148
                }
149
        }
150

151
        PostPendingActions(ex_auth_data);
18✔
152
}
153

154
} // namespace auth
155
} // namespace api
156
} // namespace mender
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc