@@ -22,21 +22,22 @@ use std::future::{ready, Ready};
2222use actix_web:: {
2323 dev:: { forward_ready, Service , ServiceRequest , ServiceResponse , Transform } ,
2424 error:: { ErrorBadRequest , ErrorUnauthorized } ,
25- Error , HttpMessage ,
25+ Error ,
2626} ;
27+ use actix_web_httpauth:: extractors:: basic:: BasicAuth ;
2728use futures_util:: future:: LocalBoxFuture ;
2829
2930use crate :: {
3031 option:: CONFIG ,
3132 rbac:: { role:: Action , Users } ,
3233} ;
3334
34- pub struct Authorization {
35+ pub struct Auth {
3536 pub action : Action ,
3637 pub stream : bool ,
3738}
3839
39- impl < S , B > Transform < S , ServiceRequest > for Authorization
40+ impl < S , B > Transform < S , ServiceRequest > for Auth
4041where
4142 S : Service < ServiceRequest , Response = ServiceResponse < B > , Error = Error > ,
4243 S :: Future : ' static ,
@@ -45,25 +46,25 @@ where
4546 type Response = ServiceResponse < B > ;
4647 type Error = Error ;
4748 type InitError = ( ) ;
48- type Transform = AuthorizationMiddleware < S > ;
49+ type Transform = AuthMiddleware < S > ;
4950 type Future = Ready < Result < Self :: Transform , Self :: InitError > > ;
5051
5152 fn new_transform ( & self , service : S ) -> Self :: Future {
52- ready ( Ok ( AuthorizationMiddleware {
53+ ready ( Ok ( AuthMiddleware {
5354 action : self . action ,
5455 match_stream : self . stream ,
5556 service,
5657 } ) )
5758 }
5859}
5960
60- pub struct AuthorizationMiddleware < S > {
61+ pub struct AuthMiddleware < S > {
6162 action : Action ,
6263 match_stream : bool ,
6364 service : S ,
6465}
6566
66- impl < S , B > Service < ServiceRequest > for AuthorizationMiddleware < S >
67+ impl < S , B > Service < ServiceRequest > for AuthMiddleware < S >
6768where
6869 S : Service < ServiceRequest , Response = ServiceResponse < B > , Error = Error > ,
6970 S :: Future : ' static ,
@@ -75,25 +76,34 @@ where
7576
7677 forward_ready ! ( service) ;
7778
78- fn call ( & self , req : ServiceRequest ) -> Self :: Future {
79+ fn call ( & self , mut req : ServiceRequest ) -> Self :: Future {
80+ // Extract username and password using basic auth extractor.
81+ let creds = req. extract :: < BasicAuth > ( ) . into_inner ( ) ;
82+ let creds = creds. map_err ( Into :: into) . map ( |creds| {
83+ let username = creds. user_id ( ) . trim ( ) . to_owned ( ) ;
84+ // password is not mandatory by basic auth standard.
85+ // If not provided then treat as empty string
86+ let password = creds. password ( ) . unwrap_or ( "" ) . trim ( ) . to_owned ( ) ;
87+ ( username, password)
88+ } ) ;
89+
7990 let stream = if self . match_stream {
8091 req. match_info ( ) . get ( "logstream" )
8192 } else {
8293 None
8394 } ;
84- let extensions = req. extensions ( ) ;
85- let username = extensions
86- . get :: < String > ( )
87- . expect ( "authentication layer verified username" ) ;
88- let is_auth = Users . check_permission ( username, self . action , stream) ;
89- drop ( extensions) ;
95+
96+ let auth_result: Result < bool , Error > = creds. map ( |( username, password) | {
97+ Users . authenticate ( username, password, self . action , stream)
98+ } ) ;
9099
91100 let fut = self . service . call ( req) ;
92101
93102 Box :: pin ( async move {
94- if !is_auth {
103+ if !auth_result? {
95104 return Err ( ErrorUnauthorized ( "Not authorized" ) ) ;
96105 }
106+
97107 fut. await
98108 } )
99109 }
0 commit comments