pub(crate) fn lua_auth(
    webnis: &Webnis,
    funcname: &str,
    req: Request,
) -> Result<(serde_json::Value, u16), WnError>
{
    let do_log = webnis.inner.config.server.datalog.is_some();

    LUA.with(|lua_tls| {
        let mut lua_state = lua_tls.borrow();
        if !lua_state.did_init {
            drop(lua_state);
            let mut lua_state_mut = lua_tls.borrow_mut();
	        let webnis = webnis.clone();
            lua_state_mut.lua.context(|ctx| set_webnis_global(ctx, webnis));
            lua_state_mut.did_init = true;
            drop(lua_state_mut);
            lua_state = lua_tls.borrow();
        }

        if do_log {
            // set up the datalog member.
            let clientip = match req.extra.get("clientip") {
                Some(serde_json::Value::String(ref s)) => s.parse::<IpAddr>().ok(),
                _ => None,
            };
            let callingsystem = match req.extra.get("callingsystem") {
                Some(serde_json::Value::String(ref s)) => Some(s.clone()),
                _ => None,
            };
            req.log.set(Datalog{
                time:   SystemTime::now(),
                username:       req.username.clone().unwrap_or("".into()),
                src_ip:         req.src_ip.unwrap_or([0, 0, 0, 0].into()),
                clientip:       clientip,
                callingsystem:  callingsystem,
                ..Datalog::default()
            });
        }
        let datalog_ref = req.log.clone();

        let res = lua_state.lua.context(|ctx| {
            let func: Function = match ctx.globals().get(funcname) {
                Ok(f) => f,
                Err(_e) => return Err(WnError::LuaFunctionNotFound),
            };

            // function can return 0, 1 or 2 values.
            let multival = match func.call::<_, rlua::MultiValue>(req) {
                Ok(v) => v,
                Err(e) => {
                    merror!("lua_auth: executing {}:\n{}", funcname, e);
                    return Err(WnError::LuaError);
                },
            };
            let mut vals = multival.into_iter();

            // first value, if present, is the returned table.
            let jv = vals
                .next()
                .map(|v| lua_value_to_json(v))
                .unwrap_or(serde_json::Value::Null);

            // second value, if present, is statuscode.
            let code = {
                match vals.next() {
                    Some(rlua::Value::Integer(n)) => {
                        if n < 100 || n > 599 {
                            merror!(
                                "lua_auth: executing {}: status code out of range: {}\n",
                                funcname,
                                n
                            );
                            return Err(WnError::LuaError);
                        }
                        n as u16
                    },
                    Some(_) => {
                        merror!("lua_auth: executing {}: status code not an integer\n", funcname);
                        return Err(WnError::LuaError);
                    },
                    None => 0,
                }
            };

            Ok((jv, code))
        });

        // See if we need to update the log status.
        if do_log {
            let mut dl = datalog_ref.0.lock().unwrap().take().unwrap();
            match res {
                Err(ref e) => {
                    // internal error, override log status.
                    dl.status = Err(datalog::Error::GENERIC);
                    dl.message = Some(format!("{:?}", e));
                },
                Ok(ref v) => {
                    if v.0 == serde_json::Value::Null || v.1 >= 400 {
                        // It's a reject, if status was not set do it now.
                        if dl.status.is_ok() {
                            dl.status = Err(datalog::Error::GENERIC);
                        }
                    }
                }
            }
            // And log.
            datalog::log_sync(dl);
        }

        res
    })
}
/// lua_auth calls a lua function.
/// returns a json value on success, json null on auth fail, error on any errors.
lua_auth calls a lua function.
returns a json value on success, json null on auth fail, error on any errors.
lua_auth calls a lua function . returns a json value on success json null on auth fail error on any errors .
pub(crate) fn lua_auth(
    webnis: &Webnis,
    funcname: &str,
    req: Request,
) -> Result<(serde_json::Value, u16), WnError>
{
    let do_log = webnis.inner.config.server.datalog.is_some();
    LUA.with(|lua_tls| {
        let mut lua_state = lua_tls.borrow();
        if !lua_state.did_init {
            drop(lua_state);
            let mut lua_state_mut = lua_tls.borrow_mut();
	        let webnis = webnis.clone();
            lua_state_mut.lua.context(|ctx| set_webnis_global(ctx, webnis));
            lua_state_mut.did_init = true;
            drop(lua_state_mut);
            lua_state = lua_tls.borrow();
        }
        if do_log {
            // set up the datalog member.
            let clientip = match req.extra.get("clientip") {
                Some(serde_json::Value::String(ref s)) => s.parse::<IpAddr>().ok(),
                _ => None,
            };
            let callingsystem = match req.extra.get("callingsystem") {
                Some(serde_json::Value::String(ref s)) => Some(s.clone()),
                _ => None,
            };
            req.log.set(Datalog{
                time:   SystemTime::now(),
                username:       req.username.clone().unwrap_or("".into()),
                src_ip:         req.src_ip.unwrap_or([0, 0, 0, 0].into()),
                clientip:       clientip,
                callingsystem:  callingsystem,
                ..Datalog::default()
            });
        }
        let datalog_ref = req.log.clone();
        let res = lua_state.lua.context(|ctx| {
            let func: Function = match ctx.globals().get(funcname) {
                Ok(f) => f,
                Err(_e) => return Err(WnError::LuaFunctionNotFound),
            };
            // function can return 0, 1 or 2 values.
            let multival = match func.call::<_, rlua::MultiValue>(req) {
                Ok(v) => v,
                Err(e) => {
                    merror!("lua_auth: executing {}:\n{}", funcname, e);
                    return Err(WnError::LuaError);
                },
            };
            let mut vals = multival.into_iter();
            // first value, if present, is the returned table.
            let jv = vals
                .next()
                .map(|v| lua_value_to_json(v))
                .unwrap_or(serde_json::Value::Null);
            // second value, if present, is statuscode.
            let code = {
                match vals.next() {
                    Some(rlua::Value::Integer(n)) => {
                        if n < 100 || n > 599 {
                            merror!(
                                "lua_auth: executing {}: status code out of range: {}\n",
                                funcname,
                                n
                            );
                            return Err(WnError::LuaError);
                        }
                        n as u16
                    },
                    Some(_) => {
                        merror!("lua_auth: executing {}: status code not an integer\n", funcname);
                        return Err(WnError::LuaError);
                    },
                    None => 0,
                }
            };
            Ok((jv, code))
        });
        // See if we need to update the log status.
        if do_log {
            let mut dl = datalog_ref.0.lock().unwrap().take().unwrap();
            match res {
                Err(ref e) => {
                    // internal error, override log status.
                    dl.status = Err(datalog::Error::GENERIC);
                    dl.message = Some(format!("{:?}", e));
                },
                Ok(ref v) => {
                    if v.0 == serde_json::Value::Null || v.1 >= 400 {
                        // It's a reject, if status was not set do it now.
                        if dl.status.is_ok() {
                            dl.status = Err(datalog::Error::GENERIC);
                        }
                    }
                }
            }
            // And log.
            datalog::log_sync(dl);
        }
        res
    })
}
pub ( crate ) fn lua_auth ( webnis : & Webnis , funcname : & str , req : Request , ) -> Result < ( serde_json :: Value , u16 ) , WnError > { let do_log = webnis . inner . config . server . datalog . is_some ( ) ; LUA . with ( | lua_tls | { let mut lua_state = lua_tls . borrow ( ) ; if ! lua_state . did_init { drop ( lua_state ) ; let mut lua_state_mut = lua_tls . borrow_mut ( ) ; let webnis = webnis . clone ( ) ; lua_state_mut . lua . context ( | ctx | set_webnis_global ( ctx , webnis ) ) ; lua_state_mut . did_init = true ; drop ( lua_state_mut ) ; lua_state = lua_tls . borrow ( ) ; } if do_log { // set up the datalog member. let clientip = match req . extra . get ( " " ) { Some ( serde_json :: Value :: String ( ref s ) ) => s . parse :: < IpAddr > ( ) . ok ( ) , _ => None , } ; let callingsystem = match req . extra . get ( " " ) { Some ( serde_json :: Value :: String ( ref s ) ) => Some ( s . clone ( ) ) , _ => None , } ; req . log . set ( Datalog { time : SystemTime :: now ( ) , username : req . username . clone ( ) . unwrap_or ( " " . into ( ) ) , src_ip : req . src_ip . unwrap_or ( [ 0 , 0 , 0 , 0 ] . into ( ) ) , clientip : clientip , callingsystem : callingsystem , .. Datalog :: default ( ) } ) ; } let datalog_ref = req . log . clone ( ) ; let res = lua_state . lua . context ( | ctx | { let func : Function = match ctx . globals ( ) . get ( funcname ) { Ok ( f ) => f , Err ( _e ) => return Err ( WnError :: LuaFunctionNotFound ) , } ; // function can return 0, 1 or 2 values. let multival = match func . call :: < _ , rlua :: MultiValue > ( req ) { Ok ( v ) => v , Err ( e ) => { merror ! ( " \n " funcname e ) ; return Err ( WnError :: LuaError ) ; } , } ; let mut vals = multival . into_iter ( ) ; // first value, if present, is the returned table. let jv = vals . next ( ) . map ( | v | lua_value_to_json ( v ) ) . unwrap_or ( serde_json :: Value :: Null ) ; // second value, if present, is statuscode. let code = { match vals . next ( ) { Some ( rlua :: Value :: Integer ( n ) ) => { if n < 100 || n > 599 { merror ! ( " \n " funcname n ) ; return Err ( WnError :: LuaError ) ; } n as u16 } , Some ( _ ) => { merror ! ( " \n " funcname ) ; return Err ( WnError :: LuaError ) ; } , None => 0 , } } ; Ok ( ( jv , code ) ) } ) ; // See if we need to update the log status. if do_log { let mut dl = datalog_ref . 0 . lock ( ) . unwrap ( ) . take ( ) . unwrap ( ) ; match res { Err ( ref e ) => { // internal error, override log status. dl . status = Err ( datalog :: Error :: GENERIC ) ; dl . message = Some ( format ! ( " " e ) ) ; } , Ok ( ref v ) => { if v . 0 == serde_json :: Value :: Null || v . 1 >= 400 { // It's a reject, if status was not set do it now. if dl . status . is_ok ( ) { dl . status = Err ( datalog :: Error :: GENERIC ) ; } } } } // And log. datalog :: log_sync ( dl ) ; } res } ) }
lua_auth calls a lua function.
lua_auth calls a lua function .
webnis
&Webnis
funcname
&str
req
Request