gstreamer_rtsp_server/subclass/
rtsp_auth.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::{ffi, RTSPAuth, RTSPContext};
4use glib::{prelude::*, subclass::prelude::*, translate::*};
5use libc::c_char;
6
7pub trait RTSPAuthImpl: RTSPAuthImplExt + ObjectImpl + Send + Sync {
8    /// check the authentication of a client. The default implementation
9    ///  checks if the authentication in the header matches one of the basic
10    ///  authentication tokens. This function should set the authgroup field
11    ///  in the context.
12    fn authenticate(&self, ctx: &RTSPContext) -> bool {
13        self.parent_authenticate(ctx)
14    }
15
16    /// check if a resource can be accessed. this function should
17    ///  call authenticate to authenticate the client when needed. The method
18    ///  should also construct and send an appropriate response message on
19    ///  error.
20    fn check(&self, ctx: &RTSPContext, check: &glib::GString) -> bool {
21        self.parent_check(ctx, check)
22    }
23
24    fn generate_authenticate_header(&self, ctx: &RTSPContext) {
25        self.parent_generate_authenticate_header(ctx);
26    }
27}
28
29mod sealed {
30    pub trait Sealed {}
31    impl<T: super::RTSPAuthImplExt> Sealed for T {}
32}
33
34pub trait RTSPAuthImplExt: sealed::Sealed + ObjectSubclass {
35    fn parent_authenticate(&self, ctx: &RTSPContext) -> bool {
36        unsafe {
37            let data = Self::type_data();
38            let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPAuthClass;
39            (*parent_class)
40                .authenticate
41                .map(|f| {
42                    from_glib(f(
43                        self.obj().unsafe_cast_ref::<RTSPAuth>().to_glib_none().0,
44                        ctx.to_glib_none().0,
45                    ))
46                })
47                .unwrap_or(false)
48        }
49    }
50
51    fn parent_check(&self, ctx: &RTSPContext, check: &glib::GString) -> bool {
52        unsafe {
53            let data = Self::type_data();
54            let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPAuthClass;
55            (*parent_class)
56                .check
57                .map(|f| {
58                    from_glib(f(
59                        self.obj().unsafe_cast_ref::<RTSPAuth>().to_glib_none().0,
60                        ctx.to_glib_none().0,
61                        check.to_glib_none().0,
62                    ))
63                })
64                .unwrap_or(false)
65        }
66    }
67
68    fn parent_generate_authenticate_header(&self, ctx: &RTSPContext) {
69        unsafe {
70            let data = Self::type_data();
71            let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPAuthClass;
72            if let Some(f) = (*parent_class).generate_authenticate_header {
73                f(
74                    self.obj().unsafe_cast_ref::<RTSPAuth>().to_glib_none().0,
75                    ctx.to_glib_none().0,
76                )
77            }
78        }
79    }
80}
81
82impl<T: RTSPAuthImpl> RTSPAuthImplExt for T {}
83
84unsafe impl<T: RTSPAuthImpl> IsSubclassable<T> for RTSPAuth {
85    fn class_init(klass: &mut glib::Class<Self>) {
86        Self::parent_class_init::<T>(klass);
87        let klass = klass.as_mut();
88        klass.authenticate = Some(rtsp_auth_authenticate::<T>);
89        klass.check = Some(rtsp_auth_check::<T>);
90        klass.generate_authenticate_header = Some(rtsp_auth_generate_authenticate_header::<T>);
91    }
92}
93
94unsafe extern "C" fn rtsp_auth_authenticate<T: RTSPAuthImpl>(
95    ptr: *mut ffi::GstRTSPAuth,
96    ctx: *mut ffi::GstRTSPContext,
97) -> glib::ffi::gboolean {
98    let instance = &*(ptr as *mut T::Instance);
99    let imp = instance.imp();
100
101    imp.authenticate(&from_glib_borrow(ctx)).into_glib()
102}
103
104unsafe extern "C" fn rtsp_auth_check<T: RTSPAuthImpl>(
105    ptr: *mut ffi::GstRTSPAuth,
106    ctx: *mut ffi::GstRTSPContext,
107    check: *const c_char,
108) -> glib::ffi::gboolean {
109    let instance = &*(ptr as *mut T::Instance);
110    let imp = instance.imp();
111
112    imp.check(&from_glib_borrow(ctx), &from_glib_borrow(check))
113        .into_glib()
114}
115
116unsafe extern "C" fn rtsp_auth_generate_authenticate_header<T: RTSPAuthImpl>(
117    ptr: *mut ffi::GstRTSPAuth,
118    ctx: *mut ffi::GstRTSPContext,
119) {
120    let instance = &*(ptr as *mut T::Instance);
121    let imp = instance.imp();
122
123    imp.generate_authenticate_header(&from_glib_borrow(ctx));
124}