Skip to content

Commit b48d2ae

Browse files
committed
Move all rest-api code out of libsplinter
This commit moves all actix-web and supporting rest-api code into the actix-web-1 and common crates. The main discriminant is 'does this have actix-web-1 stuff in it' => actix-web-1 else common. Below is an accounting of where things moved from libsplinter/src/rest_api. This commit encompasses these moves as well as updating everything in the rest_api and splinterd crates to import structs from the right places. 1 auth ====== 1.1 identity => rest_api/common/auth/identity ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1.1.1 biome.rs -------------- 1.1.2 cylinder.rs ----------------- 1.1.3 mod.rs ------------ 1.1.4 oauth.rs -------------- 1.2 mod.rs => rest_api/common/auth/{authorization_result, authorization_header, bearer_token}.mod.rs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1.3 actix.rs => rest_api/actix_web_1/auth/{transform,middleware}.rs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1.4 authorization ~~~~~~~~~~~~~~~~~ 1.4.1 permission_map.rs => Split between common/auth/permission_map.rs and actix_web_1/auth/method.rs ------------------------------------------------------------------------------------------------------ 1.4.2 rbac ---------- * 1.4.2.1 handler.rs => common/auth/rbac/handler.rs * 1.4.2.2 mod.rs * 1.4.2.3 rest_api + 1.4.2.3.1 resources => common/auth/rbac/resources - 1.4.2.3.1.1 roles.rs - 1.4.2.3.1.2 mod.rs - 1.4.2.3.1.3 assignments.rs + 1.4.2.3.2 mod.rs => delete + 1.4.2.3.3 actix_web_1 => actix_web_1/auth/rbac - 1.4.2.3.3.1 error.rs => common/auth/rbac/error.rs - 1.4.2.3.3.2 roles.rs - 1.4.2.3.3.3 mod.rs - 1.4.2.3.3.4 assignments.rs 1.4.3 mod.rs => common/auth/{permission,authorization_handler_result,authorization_handler}.rs ---------------------------------------------------------------------------------------------- * 1.4.3.1 Split * 1.4.3.2 Move 1.4.4 maintenance ----------------- * 1.4.4.1 mod.rs => split common/auth/maintenance/{maintenance_mode_authorization_handler,mod}.rs + 1.4.4.1.1 Split + 1.4.4.1.2 Move * 1.4.4.2 routes + 1.4.4.2.1 actix.rs => actix-web-1/auth/maintenance/routes.rs + 1.4.4.2.2 mod.rs => actix-web-1/auth/maintenance/mod.rs + 1.4.4.2.3 resources.rs => common/auth/maintenance/ 1.4.5 allow_keys.rs => common/auth/allow_keys.rs ------------------------------------------------ 1.4.6 routes ------------ * 1.4.6.1 mod.rs => actix-web/actix-web-1/routes/resource_provider.rs * 1.4.6.2 actix.rs => actix-web/actix-web/routes/make_permissions_resource.rs * 1.4.6.3 resources.rs => common/auth/routes?/resources.rs 2 secrets => common/auth/secrets ================================ 2.1 error.rs ~~~~~~~~~~~~ 2.2 mod.rs ~~~~~~~~~~ 2.3 auto_secret_manager.rs ~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 cors.rs => actix-web-1/auth/cors.rs ===================================== 4 response_models.rs => common/response_models.rs ================================================= 5 paging.rs => delete, already exists in common =============================================== 6 mod.rs => Split common/{OauthConfig,bind_config,mod}.rs ========================================================= 7 sessions => common/sessions/ ============================== 7.1 claims.rs ~~~~~~~~~~~~~ 7.2 token_issuer.rs ~~~~~~~~~~~~~~~~~~~ 7.3 error.rs ~~~~~~~~~~~~ 7.4 mod.rs ~~~~~~~~~~ 8 errors.rs => common/auth/error.rs =================================== Signed-off-by: Caleb Hill <hill@bitwise.io>
1 parent 7a98b24 commit b48d2ae

File tree

167 files changed

+4473
-3764
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

167 files changed

+4473
-3764
lines changed

libsplinter/Cargo.toml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ description = """\
2727
repository = "https://github.com/cargill/splinter"
2828

2929
[dependencies]
30-
actix = { version = "0.8", optional = true, default-features = false }
3130
actix-http = { version = "0.2", optional = true, default-features = false }
32-
actix-web = { version = "1.0", optional = true, default-features = false }
33-
actix-web-actors = { version = "1.0", optional = true }
3431
awc = { version = "0.2", optional = true, default-features = false }
3532
base64 = { version = "0.13", optional = true }
3633
bcrypt = {version = "0.10", optional = true}
@@ -158,7 +155,7 @@ admin-service-event-subscriber-glob = ["admin-service"]
158155
authorization-handler-allow-keys = ["authorization"]
159156
authorization-handler-maintenance = ["authorization"]
160157
authorization = ["rest-api-actix-web-1"]
161-
authorization-handler-rbac = ["authorization", "store"]
158+
authorization-handler-rbac = ["store"]
162159
biome = []
163160
biome-client = ["biome"]
164161
biome-client-reqwest = ["biome", "reqwest"]
@@ -171,7 +168,7 @@ client-reqwest = ["reqwest"]
171168
cylinder-jwt = ["cylinder/jwt", "rest-api"]
172169
deferred-send = []
173170
events = ["actix-http", "futures", "hyper", "tokio", "awc"]
174-
https-bind = ["actix-web/ssl"]
171+
https-bind = []
175172
memory = ["sqlite"]
176173
node-id-store = ["store"]
177174
oauth = ["biome", "base64", "oauth2", "reqwest", "rest-api", "store"]
@@ -182,10 +179,7 @@ registry-client-reqwest = ["registry-client", "reqwest", "rest-api"]
182179
registry-remote = ["reqwest", "registry"]
183180
rest-api = ["jsonwebtoken", "percent-encoding"]
184181
rest-api-actix-web-1 = [
185-
"actix",
186182
"actix-http",
187-
"actix-web",
188-
"actix-web-actors",
189183
"futures",
190184
"rest-api",
191185
]

libsplinter/src/admin/service/messages/v1/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub mod builder;
1717
use std::convert::TryFrom;
1818

1919
use protobuf::{self, RepeatedField};
20+
use serde::{self, Deserialize, Serialize};
2021

2122
use crate::admin::error::MarshallingError;
2223
use crate::admin::store;

libsplinter/src/biome/credentials/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,4 @@
1515
//! Defines a basic API to register and authenticate a User using a username and a password.
1616
//! Not recommended for use in production.
1717
18-
#[cfg(feature = "rest-api-actix-web-1")]
19-
pub mod rest_api;
2018
pub mod store;

libsplinter/src/biome/credentials/rest_api/mod.rs

Lines changed: 0 additions & 37 deletions
This file was deleted.

libsplinter/src/biome/profile/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,4 @@
1414

1515
//! Biome functionality to support user profiles.
1616
17-
#[cfg(feature = "rest-api-actix-web-1")]
18-
pub mod rest_api;
1917
pub mod store;

libsplinter/src/biome/profile/rest_api/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,6 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
mod actix_web_1;
16-
17-
#[cfg(feature = "authorization")]
18-
use crate::rest_api::auth::authorization::Permission;
19-
20-
pub use actix_web_1::BiomeProfileRestResourceProvider;
21-
2215
#[cfg(feature = "authorization")]
2316
const BIOME_PROFILE_READ_PERMISSION: Permission = Permission::Check {
2417
permission_id: "biome.profile.read",

libsplinter/src/lib.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717

1818
#[macro_use]
1919
extern crate log;
20-
#[cfg(any(feature = "admin-service", feature = "rest-api", feature = "registry"))]
20+
#[cfg(any(feature = "admin-service", feature = "registry"))]
2121
#[macro_use]
22+
#[cfg(any(feature = "admin-service"))]
2223
extern crate serde_derive;
2324
#[macro_use]
24-
#[cfg(feature = "rest-api-actix-web-1")]
25+
#[cfg(feature = "biome-client")]
2526
extern crate serde_json;
2627
#[macro_use]
2728
#[cfg(all(
@@ -108,11 +109,7 @@ pub mod peer;
108109
pub mod protocol;
109110
pub mod protos;
110111
pub mod public_key;
111-
#[cfg(all(
112-
feature = "rest-api",
113-
feature = "authorization",
114-
feature = "authorization-handler-rbac"
115-
))]
112+
#[cfg(all(feature = "authorization", feature = "authorization-handler-rbac"))]
116113
pub mod rbac;
117114
#[cfg(feature = "registry")]
118115
pub mod registry;

libsplinter/src/oauth/builder/openid.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
use reqwest::blocking::Client;
16+
use serde::Deserialize;
1617

1718
use crate::error::{InternalError, InvalidStateError};
1819
use crate::oauth::OpenIdProfileProvider;

libsplinter/src/oauth/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
mod builder;
1818
mod error;
1919
mod profile;
20-
#[cfg(feature = "rest-api-actix-web-1")]
21-
pub(crate) mod rest_api;
2220
pub mod store;
2321
mod subject;
2422

libsplinter/src/oauth/profile/openid.rs

Lines changed: 0 additions & 207 deletions
Original file line numberDiff line numberDiff line change
@@ -122,210 +122,3 @@ impl From<OpenIdProfileResponse> for Profile {
122122
}
123123
}
124124
}
125-
126-
#[cfg(test)]
127-
mod tests {
128-
use super::*;
129-
130-
use std::sync::mpsc::channel;
131-
use std::thread::JoinHandle;
132-
133-
use actix::System;
134-
use actix_web::{dev::Server, web, App, HttpRequest, HttpResponse, HttpServer};
135-
use futures::Future;
136-
137-
const USERINFO_ENDPOINT: &str = "/userinfo";
138-
const ALL_DETAILS_TOKEN: &str = "all_details";
139-
const ONLY_SUB_TOKEN: &str = "only_sub";
140-
const UNEXPECTED_RESPONSE_CODE_TOKEN: &str = "unexpected_response_code";
141-
const INVALID_RESPONSE_TOKEN: &str = "invalid_response";
142-
const SUB: &str = "sub";
143-
const NAME: &str = "name";
144-
const GIVEN_NAME: &str = "given_name";
145-
const FAMILY_NAME: &str = "family_name";
146-
const EMAIL: &str = "email";
147-
const PICTURE: &str = "picture";
148-
149-
/// Verifies that the OpenID profile provider correctly returns all relevant profile information
150-
/// when it's provided.
151-
///
152-
/// 1. Start the mock OpenID server
153-
/// 2. Get the profile for a user with all details filled out
154-
/// 3. Verify that all profile details are correct
155-
/// 4. Shutdown the OpenID server
156-
#[test]
157-
fn all_details() {
158-
let (shutdown_handle, address) = run_mock_openid_server("all_details");
159-
160-
let profile = OpenIdProfileProvider::new(format!("{}{}", address, USERINFO_ENDPOINT))
161-
.get_profile(ALL_DETAILS_TOKEN)
162-
.expect("Failed to get profile")
163-
.expect("Profile not found");
164-
165-
assert_eq!(&profile.subject, SUB);
166-
assert_eq!(profile.name.as_deref(), Some(NAME));
167-
assert_eq!(profile.given_name.as_deref(), Some(GIVEN_NAME));
168-
assert_eq!(profile.family_name.as_deref(), Some(FAMILY_NAME));
169-
assert_eq!(profile.email.as_deref(), Some(EMAIL));
170-
assert_eq!(profile.picture.as_deref(), Some(PICTURE));
171-
172-
shutdown_handle.shutdown();
173-
}
174-
175-
/// Verifies that the OpenID profile provider correctly returns the profile when only the
176-
/// subject is provided
177-
///
178-
/// 1. Start the mock OpenID server
179-
/// 2. Get the profile for a user with only the subject filled out
180-
/// 3. Verify that the `subject` field is correct and all other fields are empty
181-
/// 4. Shutdown the OpenID server
182-
#[test]
183-
fn only_sub() {
184-
let (shutdown_handle, address) = run_mock_openid_server("only_sub");
185-
186-
let profile = OpenIdProfileProvider::new(format!("{}{}", address, USERINFO_ENDPOINT))
187-
.get_profile(ONLY_SUB_TOKEN)
188-
.expect("Failed to get profile")
189-
.expect("Profile not found");
190-
191-
assert_eq!(&profile.subject, SUB);
192-
assert!(profile.name.is_none());
193-
assert!(profile.given_name.is_none());
194-
assert!(profile.family_name.is_none());
195-
assert!(profile.email.is_none());
196-
assert!(profile.picture.is_none());
197-
198-
shutdown_handle.shutdown();
199-
}
200-
201-
/// Verifies that the OpenID profile provider correctly returns `Ok(None)` when receiving a
202-
/// `401 Unauthorized` response from the OpenID server (which means the token is unknown).
203-
///
204-
/// 1. Start the mock OpenID server
205-
/// 2. Attempt to get the profile for an unknown token
206-
/// 3. Verify that the profile provider returns the correct value
207-
/// 4. Shutdown the OpenID server
208-
#[test]
209-
fn unauthorized_token() {
210-
let (shutdown_handle, address) = run_mock_openid_server("unauthorized_token");
211-
212-
let profile_opt = OpenIdProfileProvider::new(format!("{}{}", address, USERINFO_ENDPOINT))
213-
.get_profile("unknown_token")
214-
.expect("Failed to get profile");
215-
216-
assert!(profile_opt.is_none());
217-
218-
shutdown_handle.shutdown();
219-
}
220-
221-
/// Verifies that the OpenID profile provider correctly returns an error when receiving an
222-
/// unexpected response code from the OpenID server.
223-
///
224-
/// 1. Start the mock OpenID server
225-
/// 2. Attempt to get the profile for a token that the server will return a non-200 and non-401
226-
/// response for
227-
/// 3. Verify that the profile provider returns an error
228-
/// 4. Shutdown the OpenID server
229-
#[test]
230-
fn unexpected_response_code() {
231-
let (shutdown_handle, address) = run_mock_openid_server("unauthorized_token");
232-
233-
let profile_res = OpenIdProfileProvider::new(format!("{}{}", address, USERINFO_ENDPOINT))
234-
.get_profile(UNEXPECTED_RESPONSE_CODE_TOKEN);
235-
236-
assert!(profile_res.is_err());
237-
238-
shutdown_handle.shutdown();
239-
}
240-
241-
/// Verifies that the OpenID profile provider correctly returns an error when receiving a
242-
/// response that doesn't contain the `sub` field.
243-
///
244-
/// 1. Start the mock OpenID server
245-
/// 2. Attempt to get the profile for a token that the server will return an invalid response
246-
/// for
247-
/// 3. Verify that the profile provider returns an error
248-
/// 4. Shutdown the OpenID server
249-
#[test]
250-
fn invalid_response() {
251-
let (shutdown_handle, address) = run_mock_openid_server("unauthorized_token");
252-
253-
let profile_res = OpenIdProfileProvider::new(format!("{}{}", address, USERINFO_ENDPOINT))
254-
.get_profile(INVALID_RESPONSE_TOKEN);
255-
256-
assert!(profile_res.is_err());
257-
258-
shutdown_handle.shutdown();
259-
}
260-
261-
/// Runs a mock OAuth OpenID server and returns its shutdown handle along with the address the
262-
/// server is running on.
263-
fn run_mock_openid_server(test_name: &str) -> (OpenIDServerShutdownHandle, String) {
264-
let (tx, rx) = channel();
265-
266-
let instance_name = format!("OpenID-Server-{}", test_name);
267-
let join_handle = std::thread::Builder::new()
268-
.name(instance_name.clone())
269-
.spawn(move || {
270-
let sys = System::new(instance_name);
271-
let server = HttpServer::new(|| {
272-
App::new().service(web::resource(USERINFO_ENDPOINT).to(userinfo_endpoint))
273-
})
274-
.bind("127.0.0.1:0")
275-
.expect("Failed to bind OpenID server");
276-
let address = format!("http://127.0.0.1:{}", server.addrs()[0].port());
277-
let server = server.disable_signals().system_exit().start();
278-
tx.send((server, address)).expect("Failed to send server");
279-
sys.run().expect("OpenID server runtime failed");
280-
})
281-
.expect("Failed to spawn OpenID server thread");
282-
283-
let (server, address) = rx.recv().expect("Failed to receive server");
284-
285-
(OpenIDServerShutdownHandle(server, join_handle), address)
286-
}
287-
288-
/// The handler for the OpenID server's user info endpoint.
289-
fn userinfo_endpoint(req: HttpRequest) -> HttpResponse {
290-
match req
291-
.headers()
292-
.get("Authorization")
293-
.and_then(|auth| auth.to_str().ok())
294-
.and_then(|auth_str| auth_str.strip_prefix("Bearer "))
295-
{
296-
Some(token) if token == ALL_DETAILS_TOKEN => HttpResponse::Ok()
297-
.content_type("application/json")
298-
.json(json!({
299-
"sub": SUB,
300-
"name": NAME,
301-
"given_name": GIVEN_NAME,
302-
"family_name": FAMILY_NAME,
303-
"email": EMAIL,
304-
"picture": PICTURE,
305-
})),
306-
Some(token) if token == ONLY_SUB_TOKEN => HttpResponse::Ok()
307-
.content_type("application/json")
308-
.json(json!({
309-
"sub": SUB,
310-
})),
311-
Some(token) if token == UNEXPECTED_RESPONSE_CODE_TOKEN => {
312-
HttpResponse::BadRequest().finish()
313-
}
314-
Some(token) if token == INVALID_RESPONSE_TOKEN => HttpResponse::Ok().finish(),
315-
Some(_) => HttpResponse::Unauthorized().finish(),
316-
None => HttpResponse::BadRequest().finish(),
317-
}
318-
}
319-
320-
struct OpenIDServerShutdownHandle(Server, JoinHandle<()>);
321-
322-
impl OpenIDServerShutdownHandle {
323-
pub fn shutdown(self) {
324-
self.0
325-
.stop(false)
326-
.wait()
327-
.expect("Failed to stop OpenID server");
328-
self.1.join().expect("OpenID server thread failed");
329-
}
330-
}
331-
}

0 commit comments

Comments
 (0)