Skip to main content

ri/java/classes/
auth.rs

1//! Copyright © 2025-2026 Wenze Wei. All Rights Reserved.
2//!
3//! This file is part of Ri.
4//! The Ri project belongs to the Dunimd Team.
5//!
6//! Licensed under the Apache License, Version 2.0 (the "License");
7//! You may not use this file except in compliance with the License.
8//! You may obtain a copy of the License at
9//!
10//!     http://www.apache.org/licenses/LICENSE-2.0
11//!
12//! Unless required by applicable law or agreed to in writing, software
13//! distributed under the License is distributed on an "AS IS" BASIS,
14//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15//! See the License for the specific language governing permissions and
16//! limitations under the License.
17
18//! # Auth Module JNI Bindings
19//!
20//! JNI bindings for Ri auth classes.
21
22use crate::auth::{
23    RiAuthConfig, RiAuthModule, RiJWTClaims, RiJWTManager, RiJWTRevocationList,
24    RiJWTValidationOptions, RiOAuthManager, RiOAuthProvider, RiOAuthToken, RiOAuthUserInfo,
25    RiPermission, RiPermissionManager, RiRevokedTokenInfo, RiRole, RiSecurityManager, RiSession,
26    RiSessionManager,
27};
28use crate::java::exception::check_not_null;
29use jni::objects::{JClass, JObject, JObjectArray, JString};
30use jni::sys::{jboolean, jint, jlong, jobjectArray, jstring};
31use jni::JNIEnv;
32use std::collections::HashSet;
33
34// =============================================================================
35// RiAuthConfig JNI Bindings
36// =============================================================================
37
38#[no_mangle]
39pub extern "system" fn Java_com_dunimd_ri_auth_RiAuthConfig_new0(
40    _env: JNIEnv,
41    _class: JClass,
42) -> jlong {
43    let config = Box::new(RiAuthConfig::default());
44    Box::into_raw(config) as jlong
45}
46
47#[no_mangle]
48pub extern "system" fn Java_com_dunimd_ri_auth_RiAuthConfig_free0(
49    _env: JNIEnv,
50    _class: JClass,
51    ptr: jlong,
52) {
53    if ptr != 0 {
54        unsafe {
55            let _ = Box::from_raw(ptr as *mut RiAuthConfig);
56        }
57    }
58}
59
60// =============================================================================
61// RiAuthModule JNI Bindings
62// =============================================================================
63
64#[no_mangle]
65pub extern "system" fn Java_com_dunimd_ri_auth_RiAuthModule_new0(
66    mut env: JNIEnv,
67    _class: JClass,
68    config_ptr: jlong,
69) -> jlong {
70    if !check_not_null(&mut env, config_ptr, "RiAuthConfig") {
71        return 0;
72    }
73
74    let config = unsafe { &*(config_ptr as *const RiAuthConfig) };
75    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { RiAuthModule::new(config.clone()).await }) {
76        Some(Ok(module)) => Box::into_raw(Box::new(module)) as jlong,
77        _ => 0,
78    }
79}
80
81#[no_mangle]
82pub extern "system" fn Java_com_dunimd_ri_auth_RiAuthModule_free0(
83    _env: JNIEnv,
84    _class: JClass,
85    ptr: jlong,
86) {
87    if ptr != 0 {
88        unsafe {
89            let _ = Box::from_raw(ptr as *mut RiAuthModule);
90        }
91    }
92}
93
94// =============================================================================
95// RiJWTClaims JNI Bindings
96// =============================================================================
97
98#[no_mangle]
99pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTClaims_new0(
100    mut env: JNIEnv,
101    _class: JClass,
102    sub: JString,
103    roles: JObjectArray,
104    permissions: JObjectArray,
105) -> jlong {
106    let sub_str: String = match env.get_string(&sub) {
107        Ok(s) => s.into(),
108        Err(_) => {
109            crate::java::exception::throw_ri_error(&mut env, "Failed to get sub");
110            return 0;
111        }
112    };
113
114    let roles_len = env.get_array_length(&roles).unwrap_or(0);
115    let mut roles_vec = Vec::with_capacity(roles_len as usize);
116    for i in 0..roles_len {
117        if let Ok(elem) = env.get_object_array_element(&roles, i) {
118            let role_str: String = match env.get_string(&JString::from(elem)) {
119                Ok(s) => s.into(),
120                Err(_) => { crate::java::exception::throw_ri_error(&mut env, "Failed to read array element"); continue; }
121            };
122            roles_vec.push(role_str);
123        }
124    }
125
126    let perms_len = env.get_array_length(&permissions).unwrap_or(0);
127    let mut perms_vec = Vec::with_capacity(perms_len as usize);
128    for i in 0..perms_len {
129        if let Ok(elem) = env.get_object_array_element(&permissions, i) {
130            let perm_str: String = match env.get_string(&JString::from(elem)) {
131                Ok(s) => s.into(),
132                Err(_) => { crate::java::exception::throw_ri_error(&mut env, "Failed to read array element"); continue; }
133            };
134            perms_vec.push(perm_str);
135        }
136    }
137
138    let now = std::time::SystemTime::now()
139        .duration_since(std::time::UNIX_EPOCH)
140        .map(|d| d.as_secs())
141        .unwrap_or(0);
142
143    let claims = Box::new(RiJWTClaims {
144        sub: sub_str,
145        exp: now + 3600,
146        iat: now,
147        roles: roles_vec,
148        permissions: perms_vec,
149    });
150    Box::into_raw(claims) as jlong
151}
152
153#[no_mangle]
154pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTClaims_getSub0(
155    mut env: JNIEnv,
156    _class: JClass,
157    ptr: jlong,
158) -> jstring {
159    if !check_not_null(&mut env, ptr, "RiJWTClaims") {
160        return std::ptr::null_mut();
161    }
162
163    let claims = unsafe { &*(ptr as *const RiJWTClaims) };
164    match env.new_string(&claims.sub) {
165        Ok(s) => s.into_raw(),
166        Err(_) => std::ptr::null_mut(),
167    }
168}
169
170#[no_mangle]
171pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTClaims_getExp0(
172    mut env: JNIEnv,
173    _class: JClass,
174    ptr: jlong,
175) -> jlong {
176    if !check_not_null(&mut env, ptr, "RiJWTClaims") {
177        return 0;
178    }
179
180    let claims = unsafe { &*(ptr as *const RiJWTClaims) };
181    claims.exp as jlong
182}
183
184#[no_mangle]
185pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTClaims_getIat0(
186    mut env: JNIEnv,
187    _class: JClass,
188    ptr: jlong,
189) -> jlong {
190    if !check_not_null(&mut env, ptr, "RiJWTClaims") {
191        return 0;
192    }
193
194    let claims = unsafe { &*(ptr as *const RiJWTClaims) };
195    claims.iat as jlong
196}
197
198#[no_mangle]
199pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTClaims_getRoles0(
200    mut env: JNIEnv,
201    _class: JClass,
202    ptr: jlong,
203) -> jobjectArray {
204    if !check_not_null(&mut env, ptr, "RiJWTClaims") {
205        return std::ptr::null_mut();
206    }
207
208    let claims = unsafe { &*(ptr as *const RiJWTClaims) };
209    let roles: Vec<String> = claims.roles.clone();
210
211    let string_class = match env.find_class("java/lang/String") {
212        Ok(c) => c,
213        Err(_) => { return std::ptr::null_mut(); }
214    };
215    let array = match env.new_object_array(roles.len() as jint, string_class, JObject::null()) {
216        Ok(a) => a,
217        Err(_) => { return std::ptr::null_mut(); }
218    };
219
220    for (i, role) in roles.iter().enumerate() {
221        let jstr = match env.new_string(role) {
222            Ok(s) => s,
223            Err(_) => continue,
224        };
225        let _ = env.set_object_array_element(&array, i as jint, jstr);
226    }
227
228    array.into_raw()
229}
230
231#[no_mangle]
232pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTClaims_getPermissions0(
233    mut env: JNIEnv,
234    _class: JClass,
235    ptr: jlong,
236) -> jobjectArray {
237    if !check_not_null(&mut env, ptr, "RiJWTClaims") {
238        return std::ptr::null_mut();
239    }
240
241    let claims = unsafe { &*(ptr as *const RiJWTClaims) };
242    let perms: Vec<String> = claims.permissions.clone();
243
244    let string_class = match env.find_class("java/lang/String") {
245        Ok(c) => c,
246        Err(_) => { return std::ptr::null_mut(); }
247    };
248    let array = match env.new_object_array(perms.len() as jint, string_class, JObject::null()) {
249        Ok(a) => a,
250        Err(_) => { return std::ptr::null_mut(); }
251    };
252
253    for (i, perm) in perms.iter().enumerate() {
254        let jstr = match env.new_string(perm) {
255            Ok(s) => s,
256            Err(_) => continue,
257        };
258        let _ = env.set_object_array_element(&array, i as jint, jstr);
259    }
260
261    array.into_raw()
262}
263
264#[no_mangle]
265pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTClaims_free0(
266    _env: JNIEnv,
267    _class: JClass,
268    ptr: jlong,
269) {
270    if ptr != 0 {
271        unsafe {
272            let _ = Box::from_raw(ptr as *mut RiJWTClaims);
273        }
274    }
275}
276
277// =============================================================================
278// RiJWTValidationOptions JNI Bindings
279// =============================================================================
280
281#[no_mangle]
282pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTValidationOptions_new0(
283    _env: JNIEnv,
284    _class: JClass,
285) -> jlong {
286    let options = Box::new(RiJWTValidationOptions::default());
287    Box::into_raw(options) as jlong
288}
289
290#[no_mangle]
291pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTValidationOptions_isValidateExp0(
292    mut env: JNIEnv,
293    _class: JClass,
294    ptr: jlong,
295) -> jboolean {
296    if !check_not_null(&mut env, ptr, "RiJWTValidationOptions") {
297        return 0;
298    }
299
300    let options = unsafe { &*(ptr as *const RiJWTValidationOptions) };
301    if options.validate_exp {
302        1
303    } else {
304        0
305    }
306}
307
308#[no_mangle]
309pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTValidationOptions_setValidateExp0(
310    mut env: JNIEnv,
311    _class: JClass,
312    ptr: jlong,
313    validate: jboolean,
314) {
315    if !check_not_null(&mut env, ptr, "RiJWTValidationOptions") {
316        return;
317    }
318
319    let options = unsafe { &mut *(ptr as *mut RiJWTValidationOptions) };
320    options.validate_exp = validate != 0;
321}
322
323#[no_mangle]
324pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTValidationOptions_isValidateIat0(
325    mut env: JNIEnv,
326    _class: JClass,
327    ptr: jlong,
328) -> jboolean {
329    if !check_not_null(&mut env, ptr, "RiJWTValidationOptions") {
330        return 0;
331    }
332
333    let options = unsafe { &*(ptr as *const RiJWTValidationOptions) };
334    if options.validate_iat {
335        1
336    } else {
337        0
338    }
339}
340
341#[no_mangle]
342pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTValidationOptions_setValidateIat0(
343    mut env: JNIEnv,
344    _class: JClass,
345    ptr: jlong,
346    validate: jboolean,
347) {
348    if !check_not_null(&mut env, ptr, "RiJWTValidationOptions") {
349        return;
350    }
351
352    let options = unsafe { &mut *(ptr as *mut RiJWTValidationOptions) };
353    options.validate_iat = validate != 0;
354}
355
356#[no_mangle]
357pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTValidationOptions_getRequiredRoles0(
358    mut env: JNIEnv,
359    _class: JClass,
360    ptr: jlong,
361) -> jobjectArray {
362    if !check_not_null(&mut env, ptr, "RiJWTValidationOptions") {
363        return std::ptr::null_mut();
364    }
365
366    let options = unsafe { &*(ptr as *const RiJWTValidationOptions) };
367    let roles: Vec<String> = options.required_roles.clone();
368
369    let string_class = match env.find_class("java/lang/String") {
370        Ok(c) => c,
371        Err(_) => { return std::ptr::null_mut(); }
372    };
373    let array = match env.new_object_array(roles.len() as jint, string_class, JObject::null()) {
374        Ok(a) => a,
375        Err(_) => { return std::ptr::null_mut(); }
376    };
377
378    for (i, role) in roles.iter().enumerate() {
379        let jstr = match env.new_string(role) {
380            Ok(s) => s,
381            Err(_) => continue,
382        };
383        let _ = env.set_object_array_element(&array, i as jint, jstr);
384    }
385
386    array.into_raw()
387}
388
389#[no_mangle]
390pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTValidationOptions_setRequiredRoles0(
391    mut env: JNIEnv,
392    _class: JClass,
393    ptr: jlong,
394    roles: JObjectArray,
395) {
396    if !check_not_null(&mut env, ptr, "RiJWTValidationOptions") {
397        return;
398    }
399
400    let options = unsafe { &mut *(ptr as *mut RiJWTValidationOptions) };
401    let roles_len = env.get_array_length(&roles).unwrap_or(0);
402    let mut roles_vec = Vec::with_capacity(roles_len as usize);
403    for i in 0..roles_len {
404        if let Ok(elem) = env.get_object_array_element(&roles, i) {
405            let role_str: String = match env.get_string(&JString::from(elem)) {
406                Ok(s) => s.into(),
407                Err(_) => { crate::java::exception::throw_ri_error(&mut env, "Failed to read array element"); continue; }
408            };
409            roles_vec.push(role_str);
410        }
411    }
412    options.required_roles = roles_vec;
413}
414
415#[no_mangle]
416pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTValidationOptions_getRequiredPermissions0(
417    mut env: JNIEnv,
418    _class: JClass,
419    ptr: jlong,
420) -> jobjectArray {
421    if !check_not_null(&mut env, ptr, "RiJWTValidationOptions") {
422        return std::ptr::null_mut();
423    }
424
425    let options = unsafe { &*(ptr as *const RiJWTValidationOptions) };
426    let perms: Vec<String> = options.required_permissions.clone();
427
428    let string_class = match env.find_class("java/lang/String") {
429        Ok(c) => c,
430        Err(_) => { return std::ptr::null_mut(); }
431    };
432    let array = match env.new_object_array(perms.len() as jint, string_class, JObject::null()) {
433        Ok(a) => a,
434        Err(_) => { return std::ptr::null_mut(); }
435    };
436
437    for (i, perm) in perms.iter().enumerate() {
438        let jstr = match env.new_string(perm) {
439            Ok(s) => s,
440            Err(_) => continue,
441        };
442        let _ = env.set_object_array_element(&array, i as jint, jstr);
443    }
444
445    array.into_raw()
446}
447
448#[no_mangle]
449pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTValidationOptions_setRequiredPermissions0(
450    mut env: JNIEnv,
451    _class: JClass,
452    ptr: jlong,
453    permissions: JObjectArray,
454) {
455    if !check_not_null(&mut env, ptr, "RiJWTValidationOptions") {
456        return;
457    }
458
459    let options = unsafe { &mut *(ptr as *mut RiJWTValidationOptions) };
460    let perms_len = env.get_array_length(&permissions).unwrap_or(0);
461    let mut perms_vec = Vec::with_capacity(perms_len as usize);
462    for i in 0..perms_len {
463        if let Ok(elem) = env.get_object_array_element(&permissions, i) {
464            let perm_str: String = match env.get_string(&JString::from(elem)) {
465                Ok(s) => s.into(),
466                Err(_) => { crate::java::exception::throw_ri_error(&mut env, "Failed to read array element"); continue; }
467            };
468            perms_vec.push(perm_str);
469        }
470    }
471    options.required_permissions = perms_vec;
472}
473
474#[no_mangle]
475pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTValidationOptions_free0(
476    _env: JNIEnv,
477    _class: JClass,
478    ptr: jlong,
479) {
480    if ptr != 0 {
481        unsafe {
482            let _ = Box::from_raw(ptr as *mut RiJWTValidationOptions);
483        }
484    }
485}
486
487// =============================================================================
488// RiJWTManager JNI Bindings
489// =============================================================================
490
491#[no_mangle]
492pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTManager_generateToken0(
493    mut env: JNIEnv,
494    _class: JClass,
495    ptr: jlong,
496    claims_ptr: jlong,
497) -> jstring {
498    if !check_not_null(&mut env, ptr, "RiJWTManager") {
499        return std::ptr::null_mut();
500    }
501    if !check_not_null(&mut env, claims_ptr, "RiJWTClaims") {
502        return std::ptr::null_mut();
503    }
504
505    let manager = unsafe { &*(ptr as *const RiJWTManager) };
506    let claims = unsafe { &*(claims_ptr as *const RiJWTClaims) };
507
508    match manager.generate_token(
509        &claims.sub,
510        claims.roles.clone(),
511        claims.permissions.clone(),
512    ) {
513        Ok(token) => match env.new_string(&token) {
514        Ok(s) => s.into_raw(),
515        Err(_) => std::ptr::null_mut(),
516    },
517        Err(_) => std::ptr::null_mut(),
518    }
519}
520
521#[no_mangle]
522pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTManager_validateToken0(
523    mut env: JNIEnv,
524    _class: JClass,
525    ptr: jlong,
526    token: JString,
527) -> jlong {
528    if !check_not_null(&mut env, ptr, "RiJWTManager") {
529        return 0;
530    }
531
532    let manager = unsafe { &*(ptr as *const RiJWTManager) };
533    let token_str: String = match env.get_string(&token) {
534        Ok(s) => s.into(),
535        Err(_) => {
536            crate::java::exception::throw_ri_error(&mut env, "Failed to get token");
537            return 0;
538        }
539    };
540
541    match manager.validate_token(&token_str) {
542        Ok(claims) => {
543            let claims_box = Box::new(claims);
544            Box::into_raw(claims_box) as jlong
545        }
546        Err(_) => 0,
547    }
548}
549
550// =============================================================================
551// RiSession JNI Bindings
552// =============================================================================
553
554#[no_mangle]
555pub extern "system" fn Java_com_dunimd_ri_auth_RiSession_getId0(
556    mut env: JNIEnv,
557    _class: JClass,
558    ptr: jlong,
559) -> jstring {
560    if !check_not_null(&mut env, ptr, "RiSession") {
561        return std::ptr::null_mut();
562    }
563
564    let session = unsafe { &*(ptr as *const RiSession) };
565    match env.new_string(&session.id) {
566        Ok(s) => s.into_raw(),
567        Err(_) => std::ptr::null_mut(),
568    }
569}
570
571#[no_mangle]
572pub extern "system" fn Java_com_dunimd_ri_auth_RiSession_getUserId0(
573    mut env: JNIEnv,
574    _class: JClass,
575    ptr: jlong,
576) -> jstring {
577    if !check_not_null(&mut env, ptr, "RiSession") {
578        return std::ptr::null_mut();
579    }
580
581    let session = unsafe { &*(ptr as *const RiSession) };
582    match env.new_string(&session.user_id) {
583        Ok(s) => s.into_raw(),
584        Err(_) => std::ptr::null_mut(),
585    }
586}
587
588#[no_mangle]
589pub extern "system" fn Java_com_dunimd_ri_auth_RiSession_getCreatedAt0(
590    mut env: JNIEnv,
591    _class: JClass,
592    ptr: jlong,
593) -> jlong {
594    if !check_not_null(&mut env, ptr, "RiSession") {
595        return 0;
596    }
597
598    let session = unsafe { &*(ptr as *const RiSession) };
599    session.created_at as jlong
600}
601
602#[no_mangle]
603pub extern "system" fn Java_com_dunimd_ri_auth_RiSession_getLastAccessed0(
604    mut env: JNIEnv,
605    _class: JClass,
606    ptr: jlong,
607) -> jlong {
608    if !check_not_null(&mut env, ptr, "RiSession") {
609        return 0;
610    }
611
612    let session = unsafe { &*(ptr as *const RiSession) };
613    session.last_accessed as jlong
614}
615
616#[no_mangle]
617pub extern "system" fn Java_com_dunimd_ri_auth_RiSession_getExpiresAt0(
618    mut env: JNIEnv,
619    _class: JClass,
620    ptr: jlong,
621) -> jlong {
622    if !check_not_null(&mut env, ptr, "RiSession") {
623        return 0;
624    }
625
626    let session = unsafe { &*(ptr as *const RiSession) };
627    session.expires_at as jlong
628}
629
630#[no_mangle]
631pub extern "system" fn Java_com_dunimd_ri_auth_RiSession_getIpAddress0(
632    mut env: JNIEnv,
633    _class: JClass,
634    ptr: jlong,
635) -> jstring {
636    if !check_not_null(&mut env, ptr, "RiSession") {
637        return std::ptr::null_mut();
638    }
639
640    let session = unsafe { &*(ptr as *const RiSession) };
641    match &session.ip_address {
642        Some(ip) => match env.new_string(ip) {
643        Ok(s) => s.into_raw(),
644        Err(_) => std::ptr::null_mut(),
645    },
646        None => std::ptr::null_mut(),
647    }
648}
649
650#[no_mangle]
651pub extern "system" fn Java_com_dunimd_ri_auth_RiSession_getUserAgent0(
652    mut env: JNIEnv,
653    _class: JClass,
654    ptr: jlong,
655) -> jstring {
656    if !check_not_null(&mut env, ptr, "RiSession") {
657        return std::ptr::null_mut();
658    }
659
660    let session = unsafe { &*(ptr as *const RiSession) };
661    match &session.user_agent {
662        Some(ua) => match env.new_string(ua) {
663        Ok(s) => s.into_raw(),
664        Err(_) => std::ptr::null_mut(),
665    },
666        None => std::ptr::null_mut(),
667    }
668}
669
670#[no_mangle]
671pub extern "system" fn Java_com_dunimd_ri_auth_RiSession_isExpired0(
672    mut env: JNIEnv,
673    _class: JClass,
674    ptr: jlong,
675) -> jboolean {
676    if !check_not_null(&mut env, ptr, "RiSession") {
677        return 0;
678    }
679
680    let session = unsafe { &*(ptr as *const RiSession) };
681    if session.is_expired() {
682        1
683    } else {
684        0
685    }
686}
687
688#[no_mangle]
689pub extern "system" fn Java_com_dunimd_ri_auth_RiSession_getData0(
690    mut env: JNIEnv,
691    _class: JClass,
692    ptr: jlong,
693    key: JString,
694) -> jstring {
695    if !check_not_null(&mut env, ptr, "RiSession") {
696        return std::ptr::null_mut();
697    }
698
699    let session = unsafe { &*(ptr as *const RiSession) };
700    let key_str: String = match env.get_string(&key) {
701        Ok(s) => s.into(),
702        Err(_) => {
703            crate::java::exception::throw_ri_error(&mut env, "Failed to get key");
704            return std::ptr::null_mut();
705        }
706    };
707
708    match session.get_data(&key_str) {
709        Some(value) => match env.new_string(value) {
710        Ok(s) => s.into_raw(),
711        Err(_) => std::ptr::null_mut(),
712    },
713        None => std::ptr::null_mut(),
714    }
715}
716
717#[no_mangle]
718pub extern "system" fn Java_com_dunimd_ri_auth_RiSession_setData0(
719    mut env: JNIEnv,
720    _class: JClass,
721    ptr: jlong,
722    key: JString,
723    value: JString,
724) {
725    if !check_not_null(&mut env, ptr, "RiSession") {
726        return;
727    }
728
729    let session = unsafe { &mut *(ptr as *mut RiSession) };
730    let key_str: String = match env.get_string(&key) {
731        Ok(s) => s.into(),
732        Err(_) => {
733            crate::java::exception::throw_ri_error(&mut env, "Failed to get key");
734            return;
735        }
736    };
737    let value_str: String = match env.get_string(&value) {
738        Ok(s) => s.into(),
739        Err(_) => {
740            crate::java::exception::throw_ri_error(&mut env, "Failed to get value");
741            return;
742        }
743    };
744
745    session.set_data(key_str, value_str);
746}
747
748#[no_mangle]
749pub extern "system" fn Java_com_dunimd_ri_auth_RiSession_free0(
750    _env: JNIEnv,
751    _class: JClass,
752    ptr: jlong,
753) {
754    if ptr != 0 {
755        unsafe {
756            let _ = Box::from_raw(ptr as *mut RiSession);
757        }
758    }
759}
760
761// =============================================================================
762// RiSessionManager JNI Bindings
763// =============================================================================
764
765#[no_mangle]
766pub extern "system" fn Java_com_dunimd_ri_auth_RiSessionManager_new0(
767    _env: JNIEnv,
768    _class: JClass,
769    timeout_secs: jlong,
770) -> jlong {
771    let manager = Box::new(RiSessionManager::new(timeout_secs as u64));
772    Box::into_raw(manager) as jlong
773}
774
775#[no_mangle]
776pub extern "system" fn Java_com_dunimd_ri_auth_RiSessionManager_createSession0(
777    mut env: JNIEnv,
778    _class: JClass,
779    ptr: jlong,
780    user_id: JString,
781    ip_address: JString,
782    user_agent: JString,
783) -> jstring {
784    if !check_not_null(&mut env, ptr, "RiSessionManager") {
785        return std::ptr::null_mut();
786    }
787
788    let manager = unsafe { &*(ptr as *const RiSessionManager) };
789    let user_id_str: String = match env.get_string(&user_id) {
790        Ok(s) => s.into(),
791        Err(_) => {
792            crate::java::exception::throw_ri_error(&mut env, "Failed to get user_id");
793            return std::ptr::null_mut();
794        }
795    };
796
797    let ip_str = if ip_address.is_null() {
798        None
799    } else {
800        env.get_string(&ip_address).ok().map(|s| s.into())
801    };
802
803    let ua_str = if user_agent.is_null() {
804        None
805    } else {
806        env.get_string(&user_agent).ok().map(|s| s.into())
807    };
808
809    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.create_session(user_id_str, ip_str, ua_str).await }) {
810        Some(Ok(session_id)) => match env.new_string(&session_id) {
811        Ok(s) => s.into_raw(),
812        Err(_) => std::ptr::null_mut(),
813    },
814        _ => std::ptr::null_mut(),
815    }
816}
817
818#[no_mangle]
819pub extern "system" fn Java_com_dunimd_ri_auth_RiSessionManager_getSession0(
820    mut env: JNIEnv,
821    _class: JClass,
822    ptr: jlong,
823    session_id: JString,
824) -> jlong {
825    if !check_not_null(&mut env, ptr, "RiSessionManager") {
826        return 0;
827    }
828
829    let manager = unsafe { &*(ptr as *const RiSessionManager) };
830    let session_id_str: String = match env.get_string(&session_id) {
831        Ok(s) => s.into(),
832        Err(_) => {
833            crate::java::exception::throw_ri_error(&mut env, "Failed to get session_id");
834            return 0;
835        }
836    };
837
838    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.get_session(&session_id_str).await }) {
839        Some(Ok(Some(session))) => {
840            let session_box = Box::new(session);
841            Box::into_raw(session_box) as jlong
842        }
843        _ => 0,
844    }
845}
846
847#[no_mangle]
848pub extern "system" fn Java_com_dunimd_ri_auth_RiSessionManager_destroySession0(
849    mut env: JNIEnv,
850    _class: JClass,
851    ptr: jlong,
852    session_id: JString,
853) -> jboolean {
854    if !check_not_null(&mut env, ptr, "RiSessionManager") {
855        return 0;
856    }
857
858    let manager = unsafe { &*(ptr as *const RiSessionManager) };
859    let session_id_str: String = match env.get_string(&session_id) {
860        Ok(s) => s.into(),
861        Err(_) => {
862            crate::java::exception::throw_ri_error(&mut env, "Failed to get session_id");
863            return 0;
864        }
865    };
866
867    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.destroy_session(&session_id_str).await }) {
868        Some(Ok(result)) => {
869            if result {
870                1
871            } else {
872                0
873            }
874        }
875        _ => 0,
876    }
877}
878
879#[no_mangle]
880pub extern "system" fn Java_com_dunimd_ri_auth_RiSessionManager_extendSession0(
881    mut env: JNIEnv,
882    _class: JClass,
883    ptr: jlong,
884    session_id: JString,
885) -> jboolean {
886    if !check_not_null(&mut env, ptr, "RiSessionManager") {
887        return 0;
888    }
889
890    let manager = unsafe { &*(ptr as *const RiSessionManager) };
891    let session_id_str: String = match env.get_string(&session_id) {
892        Ok(s) => s.into(),
893        Err(_) => {
894            crate::java::exception::throw_ri_error(&mut env, "Failed to get session_id");
895            return 0;
896        }
897    };
898
899    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.extend_session(&session_id_str).await }) {
900        Some(Ok(result)) => {
901            if result {
902                1
903            } else {
904                0
905            }
906        }
907        _ => 0,
908    }
909}
910
911#[no_mangle]
912pub extern "system" fn Java_com_dunimd_ri_auth_RiSessionManager_cleanupExpired0(
913    mut env: JNIEnv,
914    _class: JClass,
915    ptr: jlong,
916) -> jint {
917    if !check_not_null(&mut env, ptr, "RiSessionManager") {
918        return 0;
919    }
920
921    let manager = unsafe { &*(ptr as *const RiSessionManager) };
922
923    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.cleanup_expired().await }) {
924        Some(Ok(count)) => count as jint,
925        _ => 0,
926    }
927}
928
929#[no_mangle]
930pub extern "system" fn Java_com_dunimd_ri_auth_RiSessionManager_getTimeout0(
931    mut env: JNIEnv,
932    _class: JClass,
933    ptr: jlong,
934) -> jlong {
935    if !check_not_null(&mut env, ptr, "RiSessionManager") {
936        return 0;
937    }
938
939    let manager = unsafe { &*(ptr as *const RiSessionManager) };
940    manager.get_timeout() as jlong
941}
942
943#[no_mangle]
944pub extern "system" fn Java_com_dunimd_ri_auth_RiSessionManager_free0(
945    _env: JNIEnv,
946    _class: JClass,
947    ptr: jlong,
948) {
949    if ptr != 0 {
950        unsafe {
951            let _ = Box::from_raw(ptr as *mut RiSessionManager);
952        }
953    }
954}
955
956// =============================================================================
957// RiPermission JNI Bindings
958// =============================================================================
959
960#[no_mangle]
961pub extern "system" fn Java_com_dunimd_ri_auth_RiPermission_new0(
962    mut env: JNIEnv,
963    _class: JClass,
964    id: JString,
965    name: JString,
966    description: JString,
967    resource: JString,
968    action: JString,
969) -> jlong {
970    let id_str: String = match env.get_string(&id) {
971        Ok(s) => s.into(),
972        Err(_) => {
973            crate::java::exception::throw_ri_error(&mut env, "Failed to get id");
974            return 0;
975        }
976    };
977    let name_str: String = match env.get_string(&name) {
978        Ok(s) => s.into(),
979        Err(_) => {
980            crate::java::exception::throw_ri_error(&mut env, "Failed to get name");
981            return 0;
982        }
983    };
984    let desc_str: String = match env.get_string(&description) {
985        Ok(s) => s.into(),
986        Err(_) => {
987            crate::java::exception::throw_ri_error(&mut env, "Failed to get description");
988            return 0;
989        }
990    };
991    let resource_str: String = match env.get_string(&resource) {
992        Ok(s) => s.into(),
993        Err(_) => {
994            crate::java::exception::throw_ri_error(&mut env, "Failed to get resource");
995            return 0;
996        }
997    };
998    let action_str: String = match env.get_string(&action) {
999        Ok(s) => s.into(),
1000        Err(_) => {
1001            crate::java::exception::throw_ri_error(&mut env, "Failed to get action");
1002            return 0;
1003        }
1004    };
1005
1006    let permission = Box::new(RiPermission {
1007        id: id_str,
1008        name: name_str,
1009        description: desc_str,
1010        resource: resource_str,
1011        action: action_str,
1012    });
1013    Box::into_raw(permission) as jlong
1014}
1015
1016#[no_mangle]
1017pub extern "system" fn Java_com_dunimd_ri_auth_RiPermission_getId0(
1018    mut env: JNIEnv,
1019    _class: JClass,
1020    ptr: jlong,
1021) -> jstring {
1022    if !check_not_null(&mut env, ptr, "RiPermission") {
1023        return std::ptr::null_mut();
1024    }
1025
1026    let permission = unsafe { &*(ptr as *const RiPermission) };
1027    match env.new_string(&permission.id) {
1028        Ok(s) => s.into_raw(),
1029        Err(_) => std::ptr::null_mut(),
1030    }
1031}
1032
1033#[no_mangle]
1034pub extern "system" fn Java_com_dunimd_ri_auth_RiPermission_getName0(
1035    mut env: JNIEnv,
1036    _class: JClass,
1037    ptr: jlong,
1038) -> jstring {
1039    if !check_not_null(&mut env, ptr, "RiPermission") {
1040        return std::ptr::null_mut();
1041    }
1042
1043    let permission = unsafe { &*(ptr as *const RiPermission) };
1044    match env.new_string(&permission.name) {
1045        Ok(s) => s.into_raw(),
1046        Err(_) => std::ptr::null_mut(),
1047    }
1048}
1049
1050#[no_mangle]
1051pub extern "system" fn Java_com_dunimd_ri_auth_RiPermission_getDescription0(
1052    mut env: JNIEnv,
1053    _class: JClass,
1054    ptr: jlong,
1055) -> jstring {
1056    if !check_not_null(&mut env, ptr, "RiPermission") {
1057        return std::ptr::null_mut();
1058    }
1059
1060    let permission = unsafe { &*(ptr as *const RiPermission) };
1061    match env.new_string(&permission.description) {
1062        Ok(s) => s.into_raw(),
1063        Err(_) => std::ptr::null_mut(),
1064    }
1065}
1066
1067#[no_mangle]
1068pub extern "system" fn Java_com_dunimd_ri_auth_RiPermission_getResource0(
1069    mut env: JNIEnv,
1070    _class: JClass,
1071    ptr: jlong,
1072) -> jstring {
1073    if !check_not_null(&mut env, ptr, "RiPermission") {
1074        return std::ptr::null_mut();
1075    }
1076
1077    let permission = unsafe { &*(ptr as *const RiPermission) };
1078    match env.new_string(&permission.resource) {
1079        Ok(s) => s.into_raw(),
1080        Err(_) => std::ptr::null_mut(),
1081    }
1082}
1083
1084#[no_mangle]
1085pub extern "system" fn Java_com_dunimd_ri_auth_RiPermission_getAction0(
1086    mut env: JNIEnv,
1087    _class: JClass,
1088    ptr: jlong,
1089) -> jstring {
1090    if !check_not_null(&mut env, ptr, "RiPermission") {
1091        return std::ptr::null_mut();
1092    }
1093
1094    let permission = unsafe { &*(ptr as *const RiPermission) };
1095    match env.new_string(&permission.action) {
1096        Ok(s) => s.into_raw(),
1097        Err(_) => std::ptr::null_mut(),
1098    }
1099}
1100
1101#[no_mangle]
1102pub extern "system" fn Java_com_dunimd_ri_auth_RiPermission_free0(
1103    _env: JNIEnv,
1104    _class: JClass,
1105    ptr: jlong,
1106) {
1107    if ptr != 0 {
1108        unsafe {
1109            let _ = Box::from_raw(ptr as *mut RiPermission);
1110        }
1111    }
1112}
1113
1114// =============================================================================
1115// RiRole JNI Bindings
1116// =============================================================================
1117
1118#[no_mangle]
1119pub extern "system" fn Java_com_dunimd_ri_auth_RiRole_new0(
1120    mut env: JNIEnv,
1121    _class: JClass,
1122    id: JString,
1123    name: JString,
1124    description: JString,
1125    permissions: JObjectArray,
1126    is_system: jboolean,
1127) -> jlong {
1128    let id_str: String = match env.get_string(&id) {
1129        Ok(s) => s.into(),
1130        Err(_) => {
1131            crate::java::exception::throw_ri_error(&mut env, "Failed to get id");
1132            return 0;
1133        }
1134    };
1135    let name_str: String = match env.get_string(&name) {
1136        Ok(s) => s.into(),
1137        Err(_) => {
1138            crate::java::exception::throw_ri_error(&mut env, "Failed to get name");
1139            return 0;
1140        }
1141    };
1142    let desc_str: String = match env.get_string(&description) {
1143        Ok(s) => s.into(),
1144        Err(_) => {
1145            crate::java::exception::throw_ri_error(&mut env, "Failed to get description");
1146            return 0;
1147        }
1148    };
1149
1150    let perms_len = env.get_array_length(&permissions).unwrap_or(0);
1151    let mut perms_set = HashSet::with_capacity(perms_len as usize);
1152    for i in 0..perms_len {
1153        if let Ok(elem) = env.get_object_array_element(&permissions, i) {
1154            let perm_str: String = match env.get_string(&JString::from(elem)) {
1155                Ok(s) => s.into(),
1156                Err(_) => { crate::java::exception::throw_ri_error(&mut env, "Failed to read array element"); continue; }
1157            };
1158            perms_set.insert(perm_str);
1159        }
1160    }
1161
1162    let role = Box::new(RiRole {
1163        id: id_str,
1164        name: name_str,
1165        description: desc_str,
1166        permissions: perms_set,
1167        is_system: is_system != 0,
1168    });
1169    Box::into_raw(role) as jlong
1170}
1171
1172#[no_mangle]
1173pub extern "system" fn Java_com_dunimd_ri_auth_RiRole_getId0(
1174    mut env: JNIEnv,
1175    _class: JClass,
1176    ptr: jlong,
1177) -> jstring {
1178    if !check_not_null(&mut env, ptr, "RiRole") {
1179        return std::ptr::null_mut();
1180    }
1181
1182    let role = unsafe { &*(ptr as *const RiRole) };
1183    match env.new_string(&role.id) {
1184        Ok(s) => s.into_raw(),
1185        Err(_) => std::ptr::null_mut(),
1186    }
1187}
1188
1189#[no_mangle]
1190pub extern "system" fn Java_com_dunimd_ri_auth_RiRole_getName0(
1191    mut env: JNIEnv,
1192    _class: JClass,
1193    ptr: jlong,
1194) -> jstring {
1195    if !check_not_null(&mut env, ptr, "RiRole") {
1196        return std::ptr::null_mut();
1197    }
1198
1199    let role = unsafe { &*(ptr as *const RiRole) };
1200    match env.new_string(&role.name) {
1201        Ok(s) => s.into_raw(),
1202        Err(_) => std::ptr::null_mut(),
1203    }
1204}
1205
1206#[no_mangle]
1207pub extern "system" fn Java_com_dunimd_ri_auth_RiRole_getDescription0(
1208    mut env: JNIEnv,
1209    _class: JClass,
1210    ptr: jlong,
1211) -> jstring {
1212    if !check_not_null(&mut env, ptr, "RiRole") {
1213        return std::ptr::null_mut();
1214    }
1215
1216    let role = unsafe { &*(ptr as *const RiRole) };
1217    match env.new_string(&role.description) {
1218        Ok(s) => s.into_raw(),
1219        Err(_) => std::ptr::null_mut(),
1220    }
1221}
1222
1223#[no_mangle]
1224pub extern "system" fn Java_com_dunimd_ri_auth_RiRole_getPermissions0(
1225    mut env: JNIEnv,
1226    _class: JClass,
1227    ptr: jlong,
1228) -> jobjectArray {
1229    if !check_not_null(&mut env, ptr, "RiRole") {
1230        return std::ptr::null_mut();
1231    }
1232
1233    let role = unsafe { &*(ptr as *const RiRole) };
1234    let perms: Vec<String> = role.permissions.iter().cloned().collect();
1235
1236    let string_class = match env.find_class("java/lang/String") {
1237        Ok(c) => c,
1238        Err(_) => { return std::ptr::null_mut(); }
1239    };
1240    let array = match env.new_object_array(perms.len() as jint, string_class, JObject::null()) {
1241        Ok(a) => a,
1242        Err(_) => { return std::ptr::null_mut(); }
1243    };
1244
1245    for (i, perm) in perms.iter().enumerate() {
1246        let jstr = match env.new_string(perm) {
1247            Ok(s) => s,
1248            Err(_) => continue,
1249        };
1250        let _ = env.set_object_array_element(&array, i as jint, jstr);
1251    }
1252
1253    array.into_raw()
1254}
1255
1256#[no_mangle]
1257pub extern "system" fn Java_com_dunimd_ri_auth_RiRole_isSystem0(
1258    mut env: JNIEnv,
1259    _class: JClass,
1260    ptr: jlong,
1261) -> jboolean {
1262    if !check_not_null(&mut env, ptr, "RiRole") {
1263        return 0;
1264    }
1265
1266    let role = unsafe { &*(ptr as *const RiRole) };
1267    if role.is_system {
1268        1
1269    } else {
1270        0
1271    }
1272}
1273
1274#[no_mangle]
1275pub extern "system" fn Java_com_dunimd_ri_auth_RiRole_hasPermission0(
1276    mut env: JNIEnv,
1277    _class: JClass,
1278    ptr: jlong,
1279    permission_id: JString,
1280) -> jboolean {
1281    if !check_not_null(&mut env, ptr, "RiRole") {
1282        return 0;
1283    }
1284
1285    let role = unsafe { &*(ptr as *const RiRole) };
1286    let perm_str: String = match env.get_string(&permission_id) {
1287        Ok(s) => s.into(),
1288        Err(_) => {
1289            crate::java::exception::throw_ri_error(&mut env, "Failed to get permission_id");
1290            return 0;
1291        }
1292    };
1293
1294    if role.has_permission(&perm_str) {
1295        1
1296    } else {
1297        0
1298    }
1299}
1300
1301#[no_mangle]
1302pub extern "system" fn Java_com_dunimd_ri_auth_RiRole_addPermission0(
1303    mut env: JNIEnv,
1304    _class: JClass,
1305    ptr: jlong,
1306    permission_id: JString,
1307) {
1308    if !check_not_null(&mut env, ptr, "RiRole") {
1309        return;
1310    }
1311
1312    let role = unsafe { &mut *(ptr as *mut RiRole) };
1313    let perm_str: String = match env.get_string(&permission_id) {
1314        Ok(s) => s.into(),
1315        Err(_) => {
1316            crate::java::exception::throw_ri_error(&mut env, "Failed to get permission_id");
1317            return;
1318        }
1319    };
1320
1321    role.add_permission(perm_str);
1322}
1323
1324#[no_mangle]
1325pub extern "system" fn Java_com_dunimd_ri_auth_RiRole_free0(
1326    _env: JNIEnv,
1327    _class: JClass,
1328    ptr: jlong,
1329) {
1330    if ptr != 0 {
1331        unsafe {
1332            let _ = Box::from_raw(ptr as *mut RiRole);
1333        }
1334    }
1335}
1336
1337// =============================================================================
1338// RiPermissionManager JNI Bindings
1339// =============================================================================
1340
1341#[no_mangle]
1342pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_new0(
1343    _env: JNIEnv,
1344    _class: JClass,
1345) -> jlong {
1346    let manager = Box::new(RiPermissionManager::new());
1347    Box::into_raw(manager) as jlong
1348}
1349
1350#[no_mangle]
1351pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_createPermission0(
1352    mut env: JNIEnv,
1353    _class: JClass,
1354    ptr: jlong,
1355    permission_ptr: jlong,
1356) {
1357    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1358        return;
1359    }
1360    if !check_not_null(&mut env, permission_ptr, "RiPermission") {
1361        return;
1362    }
1363
1364    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1365    let permission = unsafe { &*(permission_ptr as *const RiPermission) };
1366
1367    let _ = crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.create_permission(permission.clone()).await });
1368}
1369
1370#[no_mangle]
1371pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_getPermission0(
1372    mut env: JNIEnv,
1373    _class: JClass,
1374    ptr: jlong,
1375    permission_id: JString,
1376) -> jlong {
1377    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1378        return 0;
1379    }
1380
1381    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1382    let perm_id_str: String = match env.get_string(&permission_id) {
1383        Ok(s) => s.into(),
1384        Err(_) => {
1385            crate::java::exception::throw_ri_error(&mut env, "Failed to get permission_id");
1386            return 0;
1387        }
1388    };
1389
1390    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.get_permission(&perm_id_str).await }) {
1391        Some(Ok(Some(perm))) => {
1392            let perm_box = Box::new(perm);
1393            Box::into_raw(perm_box) as jlong
1394        }
1395        _ => 0,
1396    }
1397}
1398
1399#[no_mangle]
1400pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_createRole0(
1401    mut env: JNIEnv,
1402    _class: JClass,
1403    ptr: jlong,
1404    role_ptr: jlong,
1405) {
1406    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1407        return;
1408    }
1409    if !check_not_null(&mut env, role_ptr, "RiRole") {
1410        return;
1411    }
1412
1413    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1414    let role = unsafe { &*(role_ptr as *const RiRole) };
1415
1416    let _ = crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.create_role(role.clone()).await });
1417}
1418
1419#[no_mangle]
1420pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_getRole0(
1421    mut env: JNIEnv,
1422    _class: JClass,
1423    ptr: jlong,
1424    role_id: JString,
1425) -> jlong {
1426    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1427        return 0;
1428    }
1429
1430    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1431    let role_id_str: String = match env.get_string(&role_id) {
1432        Ok(s) => s.into(),
1433        Err(_) => {
1434            crate::java::exception::throw_ri_error(&mut env, "Failed to get role_id");
1435            return 0;
1436        }
1437    };
1438
1439    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.get_role(&role_id_str).await }) {
1440        Some(Ok(Some(role))) => {
1441            let role_box = Box::new(role);
1442            Box::into_raw(role_box) as jlong
1443        }
1444        _ => 0,
1445    }
1446}
1447
1448#[no_mangle]
1449pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_assignRoleToUser0(
1450    mut env: JNIEnv,
1451    _class: JClass,
1452    ptr: jlong,
1453    user_id: JString,
1454    role_id: JString,
1455) -> jboolean {
1456    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1457        return 0;
1458    }
1459
1460    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1461    let user_id_str: String = match env.get_string(&user_id) {
1462        Ok(s) => s.into(),
1463        Err(_) => {
1464            crate::java::exception::throw_ri_error(&mut env, "Failed to get user_id");
1465            return 0;
1466        }
1467    };
1468    let role_id_str: String = match env.get_string(&role_id) {
1469        Ok(s) => s.into(),
1470        Err(_) => {
1471            crate::java::exception::throw_ri_error(&mut env, "Failed to get role_id");
1472            return 0;
1473        }
1474    };
1475
1476    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.assign_role_to_user(user_id_str, role_id_str).await }) {
1477        Some(Ok(result)) => {
1478            if result {
1479                1
1480            } else {
1481                0
1482            }
1483        }
1484        _ => 0,
1485    }
1486}
1487
1488#[no_mangle]
1489pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_removeRoleFromUser0(
1490    mut env: JNIEnv,
1491    _class: JClass,
1492    ptr: jlong,
1493    user_id: JString,
1494    role_id: JString,
1495) -> jboolean {
1496    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1497        return 0;
1498    }
1499
1500    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1501    let user_id_str: String = match env.get_string(&user_id) {
1502        Ok(s) => s.into(),
1503        Err(_) => {
1504            crate::java::exception::throw_ri_error(&mut env, "Failed to get user_id");
1505            return 0;
1506        }
1507    };
1508    let role_id_str: String = match env.get_string(&role_id) {
1509        Ok(s) => s.into(),
1510        Err(_) => {
1511            crate::java::exception::throw_ri_error(&mut env, "Failed to get role_id");
1512            return 0;
1513        }
1514    };
1515
1516    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async {
1517        manager
1518            .remove_role_from_user(&user_id_str, &role_id_str)
1519            .await
1520    }) {
1521        Some(Ok(result)) => {
1522            if result {
1523                1
1524            } else {
1525                0
1526            }
1527        }
1528        _ => 0,
1529    }
1530}
1531
1532#[no_mangle]
1533pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_getUserRoles0(
1534    mut env: JNIEnv,
1535    _class: JClass,
1536    ptr: jlong,
1537    user_id: JString,
1538) -> jlongArray {
1539    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1540        return std::ptr::null_mut();
1541    }
1542
1543    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1544    let user_id_str: String = match env.get_string(&user_id) {
1545        Ok(s) => s.into(),
1546        Err(_) => {
1547            crate::java::exception::throw_ri_error(&mut env, "Failed to get user_id");
1548            return std::ptr::null_mut();
1549        }
1550    };
1551
1552    let roles = crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.get_user_roles(&user_id_str).await }).map(|r| r.unwrap_or_default())
1553        .unwrap_or_default();
1554
1555    let ptrs: Vec<jlong> = roles
1556        .into_iter()
1557        .map(|r| Box::into_raw(Box::new(r)) as jlong)
1558        .collect();
1559
1560    let array = match env.new_long_array(ptrs.len() as jint) {
1561        Ok(a) => a,
1562        Err(_) => { return std::ptr::null_mut(); }
1563    };
1564    let _ = env.set_long_array_region(&array, 0, &ptrs);
1565
1566    array.into_raw()
1567}
1568
1569use jni::sys::jlongArray;
1570
1571#[no_mangle]
1572pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_hasPermission0(
1573    mut env: JNIEnv,
1574    _class: JClass,
1575    ptr: jlong,
1576    user_id: JString,
1577    permission_id: JString,
1578) -> jboolean {
1579    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1580        return 0;
1581    }
1582
1583    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1584    let user_id_str: String = match env.get_string(&user_id) {
1585        Ok(s) => s.into(),
1586        Err(_) => {
1587            crate::java::exception::throw_ri_error(&mut env, "Failed to get user_id");
1588            return 0;
1589        }
1590    };
1591    let perm_id_str: String = match env.get_string(&permission_id) {
1592        Ok(s) => s.into(),
1593        Err(_) => {
1594            crate::java::exception::throw_ri_error(&mut env, "Failed to get permission_id");
1595            return 0;
1596        }
1597    };
1598
1599    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.has_permission(&user_id_str, &perm_id_str).await }) {
1600        Some(Ok(result)) => {
1601            if result {
1602                1
1603            } else {
1604                0
1605            }
1606        }
1607        _ => 0,
1608    }
1609}
1610
1611#[no_mangle]
1612pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_getUserPermissions0(
1613    mut env: JNIEnv,
1614    _class: JClass,
1615    ptr: jlong,
1616    user_id: JString,
1617) -> jobjectArray {
1618    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1619        return std::ptr::null_mut();
1620    }
1621
1622    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1623    let user_id_str: String = match env.get_string(&user_id) {
1624        Ok(s) => s.into(),
1625        Err(_) => {
1626            crate::java::exception::throw_ri_error(&mut env, "Failed to get user_id");
1627            return std::ptr::null_mut();
1628        }
1629    };
1630
1631    let perms = crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.get_user_permissions(&user_id_str).await }).map(|r| r.unwrap_or_default())
1632        .unwrap_or_default();
1633
1634    let perms_vec: Vec<String> = perms.into_iter().collect();
1635
1636    let string_class = match env.find_class("java/lang/String") {
1637        Ok(c) => c,
1638        Err(_) => { return std::ptr::null_mut(); }
1639    };
1640    let array = match env.new_object_array(perms_vec.len() as jint, string_class, JObject::null()) {
1641        Ok(a) => a,
1642        Err(_) => { return std::ptr::null_mut(); }
1643    };
1644
1645    for (i, perm) in perms_vec.iter().enumerate() {
1646        let jstr = match env.new_string(perm) {
1647            Ok(s) => s,
1648            Err(_) => continue,
1649        };
1650        let _ = env.set_object_array_element(&array, i as jint, jstr);
1651    }
1652
1653    array.into_raw()
1654}
1655
1656#[no_mangle]
1657pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_deletePermission0(
1658    mut env: JNIEnv,
1659    _class: JClass,
1660    ptr: jlong,
1661    permission_id: JString,
1662) -> jboolean {
1663    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1664        return 0;
1665    }
1666
1667    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1668    let perm_id_str: String = match env.get_string(&permission_id) {
1669        Ok(s) => s.into(),
1670        Err(_) => {
1671            crate::java::exception::throw_ri_error(&mut env, "Failed to get permission_id");
1672            return 0;
1673        }
1674    };
1675
1676    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.delete_permission(&perm_id_str).await }) {
1677        Some(Ok(result)) => {
1678            if result {
1679                1
1680            } else {
1681                0
1682            }
1683        }
1684        _ => 0,
1685    }
1686}
1687
1688#[no_mangle]
1689pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_deleteRole0(
1690    mut env: JNIEnv,
1691    _class: JClass,
1692    ptr: jlong,
1693    role_id: JString,
1694) -> jboolean {
1695    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1696        return 0;
1697    }
1698
1699    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1700    let role_id_str: String = match env.get_string(&role_id) {
1701        Ok(s) => s.into(),
1702        Err(_) => {
1703            crate::java::exception::throw_ri_error(&mut env, "Failed to get role_id");
1704            return 0;
1705        }
1706    };
1707
1708    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.delete_role(&role_id_str).await }) {
1709        Some(Ok(result)) => {
1710            if result {
1711                1
1712            } else {
1713                0
1714            }
1715        }
1716        _ => 0,
1717    }
1718}
1719
1720#[no_mangle]
1721pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_listPermissions0(
1722    mut env: JNIEnv,
1723    _class: JClass,
1724    ptr: jlong,
1725) -> jlongArray {
1726    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1727        return std::ptr::null_mut();
1728    }
1729
1730    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1731
1732    let perms = crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.list_permissions().await }).map(|r| r.unwrap_or_default())
1733        .unwrap_or_default();
1734
1735    let ptrs: Vec<jlong> = perms
1736        .into_iter()
1737        .map(|p| Box::into_raw(Box::new(p)) as jlong)
1738        .collect();
1739
1740    let array = match env.new_long_array(ptrs.len() as jint) {
1741        Ok(a) => a,
1742        Err(_) => { return std::ptr::null_mut(); }
1743    };
1744    let _ = env.set_long_array_region(&array, 0, &ptrs);
1745
1746    array.into_raw()
1747}
1748
1749#[no_mangle]
1750pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_listRoles0(
1751    mut env: JNIEnv,
1752    _class: JClass,
1753    ptr: jlong,
1754) -> jlongArray {
1755    if !check_not_null(&mut env, ptr, "RiPermissionManager") {
1756        return std::ptr::null_mut();
1757    }
1758
1759    let manager = unsafe { &*(ptr as *const RiPermissionManager) };
1760
1761    let roles = crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.list_roles().await }).map(|r| r.unwrap_or_default())
1762        .unwrap_or_default();
1763
1764    let ptrs: Vec<jlong> = roles
1765        .into_iter()
1766        .map(|r| Box::into_raw(Box::new(r)) as jlong)
1767        .collect();
1768
1769    let array = match env.new_long_array(ptrs.len() as jint) {
1770        Ok(a) => a,
1771        Err(_) => { return std::ptr::null_mut(); }
1772    };
1773    let _ = env.set_long_array_region(&array, 0, &ptrs);
1774
1775    array.into_raw()
1776}
1777
1778#[no_mangle]
1779pub extern "system" fn Java_com_dunimd_ri_auth_RiPermissionManager_free0(
1780    _env: JNIEnv,
1781    _class: JClass,
1782    ptr: jlong,
1783) {
1784    if ptr != 0 {
1785        unsafe {
1786            let _ = Box::from_raw(ptr as *mut RiPermissionManager);
1787        }
1788    }
1789}
1790
1791// =============================================================================
1792// RiOAuthProvider JNI Bindings
1793// =============================================================================
1794
1795#[no_mangle]
1796pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthProvider_new0(
1797    mut env: JNIEnv,
1798    _class: JClass,
1799    id: JString,
1800    name: JString,
1801    client_id: JString,
1802    client_secret: JString,
1803    auth_url: JString,
1804    token_url: JString,
1805    user_info_url: JString,
1806    scopes: JObjectArray,
1807    enabled: jboolean,
1808    redirect_uri: JString,
1809) -> jlong {
1810    let id_str: String = match env.get_string(&id) {
1811        Ok(s) => s.into(),
1812        Err(_) => {
1813            crate::java::exception::throw_ri_error(&mut env, "Failed to get id");
1814            return 0;
1815        }
1816    };
1817    let name_str: String = match env.get_string(&name) {
1818        Ok(s) => s.into(),
1819        Err(_) => {
1820            crate::java::exception::throw_ri_error(&mut env, "Failed to get name");
1821            return 0;
1822        }
1823    };
1824    let client_id_str: String = match env.get_string(&client_id) {
1825        Ok(s) => s.into(),
1826        Err(_) => {
1827            crate::java::exception::throw_ri_error(&mut env, "Failed to get client_id");
1828            return 0;
1829        }
1830    };
1831    let client_secret_str: String = match env.get_string(&client_secret) {
1832        Ok(s) => s.into(),
1833        Err(_) => {
1834            crate::java::exception::throw_ri_error(&mut env, "Failed to get client_secret");
1835            return 0;
1836        }
1837    };
1838    let auth_url_str: String = match env.get_string(&auth_url) {
1839        Ok(s) => s.into(),
1840        Err(_) => {
1841            crate::java::exception::throw_ri_error(&mut env, "Failed to get auth_url");
1842            return 0;
1843        }
1844    };
1845    let token_url_str: String = match env.get_string(&token_url) {
1846        Ok(s) => s.into(),
1847        Err(_) => {
1848            crate::java::exception::throw_ri_error(&mut env, "Failed to get token_url");
1849            return 0;
1850        }
1851    };
1852    let user_info_url_str: String = match env.get_string(&user_info_url) {
1853        Ok(s) => s.into(),
1854        Err(_) => {
1855            crate::java::exception::throw_ri_error(&mut env, "Failed to get user_info_url");
1856            return 0;
1857        }
1858    };
1859
1860    let scopes_len = env.get_array_length(&scopes).unwrap_or(0);
1861    let mut scopes_vec = Vec::with_capacity(scopes_len as usize);
1862    for i in 0..scopes_len {
1863        if let Ok(elem) = env.get_object_array_element(&scopes, i) {
1864            let scope_str: String = match env.get_string(&JString::from(elem)) {
1865                Ok(s) => s.into(),
1866                Err(_) => { crate::java::exception::throw_ri_error(&mut env, "Failed to read array element"); continue; }
1867            };
1868            scopes_vec.push(scope_str);
1869        }
1870    }
1871
1872    let redirect_uri_opt = if redirect_uri.is_null() {
1873        None
1874    } else {
1875        env.get_string(&redirect_uri).ok().map(|s| s.into())
1876    };
1877
1878    let provider = Box::new(RiOAuthProvider {
1879        id: id_str,
1880        name: name_str,
1881        client_id: client_id_str,
1882        client_secret: client_secret_str,
1883        auth_url: auth_url_str,
1884        token_url: token_url_str,
1885        user_info_url: user_info_url_str,
1886        scopes: scopes_vec,
1887        enabled: enabled != 0,
1888        redirect_uri: redirect_uri_opt,
1889        allowed_redirect_uris: Vec::new(),
1890    });
1891    Box::into_raw(provider) as jlong
1892}
1893
1894#[no_mangle]
1895pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthProvider_getId0(
1896    mut env: JNIEnv,
1897    _class: JClass,
1898    ptr: jlong,
1899) -> jstring {
1900    if !check_not_null(&mut env, ptr, "RiOAuthProvider") {
1901        return std::ptr::null_mut();
1902    }
1903
1904    let provider = unsafe { &*(ptr as *const RiOAuthProvider) };
1905    match env.new_string(&provider.id) {
1906        Ok(s) => s.into_raw(),
1907        Err(_) => std::ptr::null_mut(),
1908    }
1909}
1910
1911#[no_mangle]
1912pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthProvider_getName0(
1913    mut env: JNIEnv,
1914    _class: JClass,
1915    ptr: jlong,
1916) -> jstring {
1917    if !check_not_null(&mut env, ptr, "RiOAuthProvider") {
1918        return std::ptr::null_mut();
1919    }
1920
1921    let provider = unsafe { &*(ptr as *const RiOAuthProvider) };
1922    match env.new_string(&provider.name) {
1923        Ok(s) => s.into_raw(),
1924        Err(_) => std::ptr::null_mut(),
1925    }
1926}
1927
1928#[no_mangle]
1929pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthProvider_getClientId0(
1930    mut env: JNIEnv,
1931    _class: JClass,
1932    ptr: jlong,
1933) -> jstring {
1934    if !check_not_null(&mut env, ptr, "RiOAuthProvider") {
1935        return std::ptr::null_mut();
1936    }
1937
1938    let provider = unsafe { &*(ptr as *const RiOAuthProvider) };
1939    match env.new_string(&provider.client_id) {
1940        Ok(s) => s.into_raw(),
1941        Err(_) => std::ptr::null_mut(),
1942    }
1943}
1944
1945#[no_mangle]
1946pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthProvider_getAuthUrl0(
1947    mut env: JNIEnv,
1948    _class: JClass,
1949    ptr: jlong,
1950) -> jstring {
1951    if !check_not_null(&mut env, ptr, "RiOAuthProvider") {
1952        return std::ptr::null_mut();
1953    }
1954
1955    let provider = unsafe { &*(ptr as *const RiOAuthProvider) };
1956    match env.new_string(&provider.auth_url) {
1957        Ok(s) => s.into_raw(),
1958        Err(_) => std::ptr::null_mut(),
1959    }
1960}
1961
1962#[no_mangle]
1963pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthProvider_getTokenUrl0(
1964    mut env: JNIEnv,
1965    _class: JClass,
1966    ptr: jlong,
1967) -> jstring {
1968    if !check_not_null(&mut env, ptr, "RiOAuthProvider") {
1969        return std::ptr::null_mut();
1970    }
1971
1972    let provider = unsafe { &*(ptr as *const RiOAuthProvider) };
1973    match env.new_string(&provider.token_url) {
1974        Ok(s) => s.into_raw(),
1975        Err(_) => std::ptr::null_mut(),
1976    }
1977}
1978
1979#[no_mangle]
1980pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthProvider_getUserInfoUrl0(
1981    mut env: JNIEnv,
1982    _class: JClass,
1983    ptr: jlong,
1984) -> jstring {
1985    if !check_not_null(&mut env, ptr, "RiOAuthProvider") {
1986        return std::ptr::null_mut();
1987    }
1988
1989    let provider = unsafe { &*(ptr as *const RiOAuthProvider) };
1990    match env.new_string(&provider.user_info_url) {
1991        Ok(s) => s.into_raw(),
1992        Err(_) => std::ptr::null_mut(),
1993    }
1994}
1995
1996#[no_mangle]
1997pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthProvider_getScopes0(
1998    mut env: JNIEnv,
1999    _class: JClass,
2000    ptr: jlong,
2001) -> jobjectArray {
2002    if !check_not_null(&mut env, ptr, "RiOAuthProvider") {
2003        return std::ptr::null_mut();
2004    }
2005
2006    let provider = unsafe { &*(ptr as *const RiOAuthProvider) };
2007
2008    let string_class = match env.find_class("java/lang/String") {
2009        Ok(c) => c,
2010        Err(_) => { return std::ptr::null_mut(); }
2011    };
2012    let array = match env.new_object_array(
2013            provider.scopes.len() as jint,
2014            string_class,
2015            JObject::null(),
2016        ) {
2017        Ok(a) => a,
2018        Err(_) => { return std::ptr::null_mut(); }
2019    };
2020
2021    for (i, scope) in provider.scopes.iter().enumerate() {
2022        let jstr = match env.new_string(scope) {
2023            Ok(s) => s,
2024            Err(_) => continue,
2025        };
2026        let _ = env.set_object_array_element(&array, i as jint, jstr);
2027    }
2028
2029    array.into_raw()
2030}
2031
2032#[no_mangle]
2033pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthProvider_isEnabled0(
2034    mut env: JNIEnv,
2035    _class: JClass,
2036    ptr: jlong,
2037) -> jboolean {
2038    if !check_not_null(&mut env, ptr, "RiOAuthProvider") {
2039        return 0;
2040    }
2041
2042    let provider = unsafe { &*(ptr as *const RiOAuthProvider) };
2043    if provider.enabled {
2044        1
2045    } else {
2046        0
2047    }
2048}
2049
2050#[no_mangle]
2051pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthProvider_getRedirectUri0(
2052    mut env: JNIEnv,
2053    _class: JClass,
2054    ptr: jlong,
2055) -> jstring {
2056    if !check_not_null(&mut env, ptr, "RiOAuthProvider") {
2057        return std::ptr::null_mut();
2058    }
2059
2060    let provider = unsafe { &*(ptr as *const RiOAuthProvider) };
2061    match &provider.redirect_uri {
2062        Some(uri) => match env.new_string(uri) {
2063        Ok(s) => s.into_raw(),
2064        Err(_) => std::ptr::null_mut(),
2065    },
2066        None => std::ptr::null_mut(),
2067    }
2068}
2069
2070#[no_mangle]
2071pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthProvider_free0(
2072    _env: JNIEnv,
2073    _class: JClass,
2074    ptr: jlong,
2075) {
2076    if ptr != 0 {
2077        unsafe {
2078            let _ = Box::from_raw(ptr as *mut RiOAuthProvider);
2079        }
2080    }
2081}
2082
2083// =============================================================================
2084// RiOAuthToken JNI Bindings
2085// =============================================================================
2086
2087#[no_mangle]
2088pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthToken_new0(
2089    mut env: JNIEnv,
2090    _class: JClass,
2091    access_token: JString,
2092    token_type: JString,
2093    refresh_token: JString,
2094    scope: JString,
2095    expires_in: jlong,
2096) -> jlong {
2097    let access_token_str: String = match env.get_string(&access_token) {
2098        Ok(s) => s.into(),
2099        Err(_) => {
2100            crate::java::exception::throw_ri_error(&mut env, "Failed to get access_token");
2101            return 0;
2102        }
2103    };
2104    let token_type_str: String = match env.get_string(&token_type) {
2105        Ok(s) => s.into(),
2106        Err(_) => {
2107            crate::java::exception::throw_ri_error(&mut env, "Failed to get token_type");
2108            return 0;
2109        }
2110    };
2111    let refresh_token_opt = if refresh_token.is_null() {
2112        None
2113    } else {
2114        env.get_string(&refresh_token).ok().map(|s| s.into())
2115    };
2116    let scope_opt = if scope.is_null() {
2117        None
2118    } else {
2119        env.get_string(&scope).ok().map(|s| s.into())
2120    };
2121
2122    let token = Box::new(RiOAuthToken {
2123        access_token: access_token_str,
2124        token_type: token_type_str,
2125        refresh_token: refresh_token_opt,
2126        scope: scope_opt,
2127        expires_in: Some(expires_in),
2128    });
2129    Box::into_raw(token) as jlong
2130}
2131
2132#[no_mangle]
2133pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthToken_getAccessToken0(
2134    mut env: JNIEnv,
2135    _class: JClass,
2136    ptr: jlong,
2137) -> jstring {
2138    if !check_not_null(&mut env, ptr, "RiOAuthToken") {
2139        return std::ptr::null_mut();
2140    }
2141
2142    let token = unsafe { &*(ptr as *const RiOAuthToken) };
2143    match env.new_string(&token.access_token) {
2144        Ok(s) => s.into_raw(),
2145        Err(_) => std::ptr::null_mut(),
2146    }
2147}
2148
2149#[no_mangle]
2150pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthToken_getTokenType0(
2151    mut env: JNIEnv,
2152    _class: JClass,
2153    ptr: jlong,
2154) -> jstring {
2155    if !check_not_null(&mut env, ptr, "RiOAuthToken") {
2156        return std::ptr::null_mut();
2157    }
2158
2159    let token = unsafe { &*(ptr as *const RiOAuthToken) };
2160    match env.new_string(&token.token_type) {
2161        Ok(s) => s.into_raw(),
2162        Err(_) => std::ptr::null_mut(),
2163    }
2164}
2165
2166#[no_mangle]
2167pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthToken_getRefreshToken0(
2168    mut env: JNIEnv,
2169    _class: JClass,
2170    ptr: jlong,
2171) -> jstring {
2172    if !check_not_null(&mut env, ptr, "RiOAuthToken") {
2173        return std::ptr::null_mut();
2174    }
2175
2176    let token = unsafe { &*(ptr as *const RiOAuthToken) };
2177    match &token.refresh_token {
2178        Some(rt) => match env.new_string(rt) {
2179        Ok(s) => s.into_raw(),
2180        Err(_) => std::ptr::null_mut(),
2181    },
2182        None => std::ptr::null_mut(),
2183    }
2184}
2185
2186#[no_mangle]
2187pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthToken_getScope0(
2188    mut env: JNIEnv,
2189    _class: JClass,
2190    ptr: jlong,
2191) -> jstring {
2192    if !check_not_null(&mut env, ptr, "RiOAuthToken") {
2193        return std::ptr::null_mut();
2194    }
2195
2196    let token = unsafe { &*(ptr as *const RiOAuthToken) };
2197    match &token.scope {
2198        Some(s) => match env.new_string(s) {
2199        Ok(s) => s.into_raw(),
2200        Err(_) => std::ptr::null_mut(),
2201    },
2202        None => std::ptr::null_mut(),
2203    }
2204}
2205
2206#[no_mangle]
2207pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthToken_getExpiresIn0(
2208    mut env: JNIEnv,
2209    _class: JClass,
2210    ptr: jlong,
2211) -> jlong {
2212    if !check_not_null(&mut env, ptr, "RiOAuthToken") {
2213        return 0;
2214    }
2215
2216    let token = unsafe { &*(ptr as *const RiOAuthToken) };
2217    token.expires_in.unwrap_or(0)
2218}
2219
2220#[no_mangle]
2221pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthToken_free0(
2222    _env: JNIEnv,
2223    _class: JClass,
2224    ptr: jlong,
2225) {
2226    if ptr != 0 {
2227        unsafe {
2228            let _ = Box::from_raw(ptr as *mut RiOAuthToken);
2229        }
2230    }
2231}
2232
2233// =============================================================================
2234// RiOAuthUserInfo JNI Bindings
2235// =============================================================================
2236
2237#[no_mangle]
2238pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthUserInfo_new0(
2239    mut env: JNIEnv,
2240    _class: JClass,
2241    id: JString,
2242    email: JString,
2243    name: JString,
2244    avatar_url: JString,
2245    provider: JString,
2246) -> jlong {
2247    let id_str: String = match env.get_string(&id) {
2248        Ok(s) => s.into(),
2249        Err(_) => {
2250            crate::java::exception::throw_ri_error(&mut env, "Failed to get id");
2251            return 0;
2252        }
2253    };
2254    let email_str: String = match env.get_string(&email) {
2255        Ok(s) => s.into(),
2256        Err(_) => {
2257            crate::java::exception::throw_ri_error(&mut env, "Failed to get email");
2258            return 0;
2259        }
2260    };
2261    let name_opt = if name.is_null() {
2262        None
2263    } else {
2264        env.get_string(&name).ok().map(|s| s.into())
2265    };
2266    let avatar_url_opt = if avatar_url.is_null() {
2267        None
2268    } else {
2269        env.get_string(&avatar_url).ok().map(|s| s.into())
2270    };
2271    let provider_str: String = match env.get_string(&provider) {
2272        Ok(s) => s.into(),
2273        Err(_) => {
2274            crate::java::exception::throw_ri_error(&mut env, "Failed to get provider");
2275            return 0;
2276        }
2277    };
2278
2279    let user_info = Box::new(RiOAuthUserInfo {
2280        id: id_str,
2281        email: email_str,
2282        name: name_opt,
2283        avatar_url: avatar_url_opt,
2284        provider: provider_str,
2285    });
2286    Box::into_raw(user_info) as jlong
2287}
2288
2289#[no_mangle]
2290pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthUserInfo_getId0(
2291    mut env: JNIEnv,
2292    _class: JClass,
2293    ptr: jlong,
2294) -> jstring {
2295    if !check_not_null(&mut env, ptr, "RiOAuthUserInfo") {
2296        return std::ptr::null_mut();
2297    }
2298
2299    let user_info = unsafe { &*(ptr as *const RiOAuthUserInfo) };
2300    match env.new_string(&user_info.id) {
2301        Ok(s) => s.into_raw(),
2302        Err(_) => std::ptr::null_mut(),
2303    }
2304}
2305
2306#[no_mangle]
2307pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthUserInfo_getEmail0(
2308    mut env: JNIEnv,
2309    _class: JClass,
2310    ptr: jlong,
2311) -> jstring {
2312    if !check_not_null(&mut env, ptr, "RiOAuthUserInfo") {
2313        return std::ptr::null_mut();
2314    }
2315
2316    let user_info = unsafe { &*(ptr as *const RiOAuthUserInfo) };
2317    match env.new_string(&user_info.email) {
2318        Ok(s) => s.into_raw(),
2319        Err(_) => std::ptr::null_mut(),
2320    }
2321}
2322
2323#[no_mangle]
2324pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthUserInfo_getName0(
2325    mut env: JNIEnv,
2326    _class: JClass,
2327    ptr: jlong,
2328) -> jstring {
2329    if !check_not_null(&mut env, ptr, "RiOAuthUserInfo") {
2330        return std::ptr::null_mut();
2331    }
2332
2333    let user_info = unsafe { &*(ptr as *const RiOAuthUserInfo) };
2334    match &user_info.name {
2335        Some(n) => match env.new_string(n) {
2336        Ok(s) => s.into_raw(),
2337        Err(_) => std::ptr::null_mut(),
2338    },
2339        None => std::ptr::null_mut(),
2340    }
2341}
2342
2343#[no_mangle]
2344pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthUserInfo_getAvatarUrl0(
2345    mut env: JNIEnv,
2346    _class: JClass,
2347    ptr: jlong,
2348) -> jstring {
2349    if !check_not_null(&mut env, ptr, "RiOAuthUserInfo") {
2350        return std::ptr::null_mut();
2351    }
2352
2353    let user_info = unsafe { &*(ptr as *const RiOAuthUserInfo) };
2354    match &user_info.avatar_url {
2355        Some(url) => match env.new_string(url) {
2356        Ok(s) => s.into_raw(),
2357        Err(_) => std::ptr::null_mut(),
2358    },
2359        None => std::ptr::null_mut(),
2360    }
2361}
2362
2363#[no_mangle]
2364pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthUserInfo_getProvider0(
2365    mut env: JNIEnv,
2366    _class: JClass,
2367    ptr: jlong,
2368) -> jstring {
2369    if !check_not_null(&mut env, ptr, "RiOAuthUserInfo") {
2370        return std::ptr::null_mut();
2371    }
2372
2373    let user_info = unsafe { &*(ptr as *const RiOAuthUserInfo) };
2374    match env.new_string(&user_info.provider) {
2375        Ok(s) => s.into_raw(),
2376        Err(_) => std::ptr::null_mut(),
2377    }
2378}
2379
2380#[no_mangle]
2381pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthUserInfo_free0(
2382    _env: JNIEnv,
2383    _class: JClass,
2384    ptr: jlong,
2385) {
2386    if ptr != 0 {
2387        unsafe {
2388            let _ = Box::from_raw(ptr as *mut RiOAuthUserInfo);
2389        }
2390    }
2391}
2392
2393// =============================================================================
2394// RiOAuthManager JNI Bindings
2395// =============================================================================
2396
2397#[no_mangle]
2398pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_new0(
2399    _env: JNIEnv,
2400    _class: JClass,
2401) -> jlong {
2402    use crate::cache::RiMemoryCache;
2403    use std::sync::Arc;
2404
2405    let cache = Arc::new(RiMemoryCache::new());
2406    let manager = Box::new(RiOAuthManager::new(cache));
2407    Box::into_raw(manager) as jlong
2408}
2409
2410#[no_mangle]
2411pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_registerProvider0(
2412    mut env: JNIEnv,
2413    _class: JClass,
2414    ptr: jlong,
2415    provider_ptr: jlong,
2416) {
2417    if !check_not_null(&mut env, ptr, "RiOAuthManager") {
2418        return;
2419    }
2420    if !check_not_null(&mut env, provider_ptr, "RiOAuthProvider") {
2421        return;
2422    }
2423
2424    let manager = unsafe { &*(ptr as *const RiOAuthManager) };
2425    let provider = unsafe { &*(provider_ptr as *const RiOAuthProvider) };
2426
2427    let _ = crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.register_provider(provider.clone()).await });
2428}
2429
2430#[no_mangle]
2431pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_getProvider0(
2432    mut env: JNIEnv,
2433    _class: JClass,
2434    ptr: jlong,
2435    provider_id: JString,
2436) -> jlong {
2437    if !check_not_null(&mut env, ptr, "RiOAuthManager") {
2438        return 0;
2439    }
2440
2441    let manager = unsafe { &*(ptr as *const RiOAuthManager) };
2442    let provider_id_str: String = match env.get_string(&provider_id) {
2443        Ok(s) => s.into(),
2444        Err(_) => {
2445            crate::java::exception::throw_ri_error(&mut env, "Failed to get provider_id");
2446            return 0;
2447        }
2448    };
2449
2450    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.get_provider(&provider_id_str).await }) {
2451        Some(Ok(Some(provider))) => {
2452            let provider_box = Box::new(provider);
2453            Box::into_raw(provider_box) as jlong
2454        }
2455        _ => 0,
2456    }
2457}
2458
2459#[no_mangle]
2460pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_getAuthUrl0(
2461    mut env: JNIEnv,
2462    _class: JClass,
2463    ptr: jlong,
2464    provider_id: JString,
2465    state: JString,
2466) -> jstring {
2467    if !check_not_null(&mut env, ptr, "RiOAuthManager") {
2468        return std::ptr::null_mut();
2469    }
2470
2471    let manager = unsafe { &*(ptr as *const RiOAuthManager) };
2472    let provider_id_str: String = match env.get_string(&provider_id) {
2473        Ok(s) => s.into(),
2474        Err(_) => {
2475            crate::java::exception::throw_ri_error(&mut env, "Failed to get provider_id");
2476            return std::ptr::null_mut();
2477        }
2478    };
2479    let state_str: String = match env.get_string(&state) {
2480        Ok(s) => s.into(),
2481        Err(_) => {
2482            crate::java::exception::throw_ri_error(&mut env, "Failed to get state");
2483            return std::ptr::null_mut();
2484        }
2485    };
2486
2487    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.get_auth_url(&provider_id_str, &state_str).await }) {
2488        Some(Ok(Some(url))) => match env.new_string(&url) {
2489        Ok(s) => s.into_raw(),
2490        Err(_) => std::ptr::null_mut(),
2491    },
2492        _ => std::ptr::null_mut(),
2493    }
2494}
2495
2496#[no_mangle]
2497pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_exchangeCodeForToken0(
2498    mut env: JNIEnv,
2499    _class: JClass,
2500    ptr: jlong,
2501    provider_id: JString,
2502    code: JString,
2503    redirect_uri: JString,
2504) -> jlong {
2505    if !check_not_null(&mut env, ptr, "RiOAuthManager") {
2506        return 0;
2507    }
2508
2509    let manager = unsafe { &*(ptr as *const RiOAuthManager) };
2510    let provider_id_str: String = match env.get_string(&provider_id) {
2511        Ok(s) => s.into(),
2512        Err(_) => {
2513            crate::java::exception::throw_ri_error(&mut env, "Failed to get provider_id");
2514            return 0;
2515        }
2516    };
2517    let code_str: String = match env.get_string(&code) {
2518        Ok(s) => s.into(),
2519        Err(_) => {
2520            crate::java::exception::throw_ri_error(&mut env, "Failed to get code");
2521            return 0;
2522        }
2523    };
2524    let redirect_uri_str: String = match env.get_string(&redirect_uri) {
2525        Ok(s) => s.into(),
2526        Err(_) => {
2527            crate::java::exception::throw_ri_error(&mut env, "Failed to get redirect_uri");
2528            return 0;
2529        }
2530    };
2531
2532    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async {
2533        manager
2534            .exchange_code_for_token(&provider_id_str, &code_str, &redirect_uri_str)
2535            .await
2536    }) {
2537        Some(Ok(Some(token))) => {
2538            let token_box = Box::new(token);
2539            Box::into_raw(token_box) as jlong
2540        }
2541        _ => 0,
2542    }
2543}
2544
2545#[no_mangle]
2546pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_getUserInfo0(
2547    mut env: JNIEnv,
2548    _class: JClass,
2549    ptr: jlong,
2550    provider_id: JString,
2551    access_token: JString,
2552) -> jlong {
2553    if !check_not_null(&mut env, ptr, "RiOAuthManager") {
2554        return 0;
2555    }
2556
2557    let manager = unsafe { &*(ptr as *const RiOAuthManager) };
2558    let provider_id_str: String = match env.get_string(&provider_id) {
2559        Ok(s) => s.into(),
2560        Err(_) => {
2561            crate::java::exception::throw_ri_error(&mut env, "Failed to get provider_id");
2562            return 0;
2563        }
2564    };
2565    let access_token_str: String = match env.get_string(&access_token) {
2566        Ok(s) => s.into(),
2567        Err(_) => {
2568            crate::java::exception::throw_ri_error(&mut env, "Failed to get access_token");
2569            return 0;
2570        }
2571    };
2572
2573    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async {
2574        manager
2575            .get_user_info(&provider_id_str, &access_token_str)
2576            .await
2577    }) {
2578        Some(Ok(Some(user_info))) => {
2579            let user_info_box = Box::new(user_info);
2580            Box::into_raw(user_info_box) as jlong
2581        }
2582        _ => 0,
2583    }
2584}
2585
2586#[no_mangle]
2587pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_refreshToken0(
2588    mut env: JNIEnv,
2589    _class: JClass,
2590    ptr: jlong,
2591    provider_id: JString,
2592    refresh_token: JString,
2593) -> jlong {
2594    if !check_not_null(&mut env, ptr, "RiOAuthManager") {
2595        return 0;
2596    }
2597
2598    let manager = unsafe { &*(ptr as *const RiOAuthManager) };
2599    let provider_id_str: String = match env.get_string(&provider_id) {
2600        Ok(s) => s.into(),
2601        Err(_) => {
2602            crate::java::exception::throw_ri_error(&mut env, "Failed to get provider_id");
2603            return 0;
2604        }
2605    };
2606    let refresh_token_str: String = match env.get_string(&refresh_token) {
2607        Ok(s) => s.into(),
2608        Err(_) => {
2609            crate::java::exception::throw_ri_error(&mut env, "Failed to get refresh_token");
2610            return 0;
2611        }
2612    };
2613
2614    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async {
2615        manager
2616            .refresh_token(&provider_id_str, &refresh_token_str)
2617            .await
2618    }) {
2619        Some(Ok(Some(token))) => {
2620            let token_box = Box::new(token);
2621            Box::into_raw(token_box) as jlong
2622        }
2623        _ => 0,
2624    }
2625}
2626
2627#[no_mangle]
2628pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_revokeToken0(
2629    mut env: JNIEnv,
2630    _class: JClass,
2631    ptr: jlong,
2632    provider_id: JString,
2633    access_token: JString,
2634) -> jboolean {
2635    if !check_not_null(&mut env, ptr, "RiOAuthManager") {
2636        return 0;
2637    }
2638
2639    let manager = unsafe { &*(ptr as *const RiOAuthManager) };
2640    let provider_id_str: String = match env.get_string(&provider_id) {
2641        Ok(s) => s.into(),
2642        Err(_) => {
2643            crate::java::exception::throw_ri_error(&mut env, "Failed to get provider_id");
2644            return 0;
2645        }
2646    };
2647    let access_token_str: String = match env.get_string(&access_token) {
2648        Ok(s) => s.into(),
2649        Err(_) => {
2650            crate::java::exception::throw_ri_error(&mut env, "Failed to get access_token");
2651            return 0;
2652        }
2653    };
2654
2655    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async {
2656        manager
2657            .revoke_token(&provider_id_str, &access_token_str)
2658            .await
2659    }) {
2660        Some(Ok(result)) => {
2661            if result {
2662                1
2663            } else {
2664                0
2665            }
2666        }
2667        _ => 0,
2668    }
2669}
2670
2671#[no_mangle]
2672pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_listProviders0(
2673    mut env: JNIEnv,
2674    _class: JClass,
2675    ptr: jlong,
2676) -> jlongArray {
2677    if !check_not_null(&mut env, ptr, "RiOAuthManager") {
2678        return std::ptr::null_mut();
2679    }
2680
2681    let manager = unsafe { &*(ptr as *const RiOAuthManager) };
2682
2683    let providers = crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.list_providers().await }).map(|r| r.unwrap_or_default())
2684        .unwrap_or_default();
2685
2686    let ptrs: Vec<jlong> = providers
2687        .into_iter()
2688        .map(|p| Box::into_raw(Box::new(p)) as jlong)
2689        .collect();
2690
2691    let array = match env.new_long_array(ptrs.len() as jint) {
2692        Ok(a) => a,
2693        Err(_) => { return std::ptr::null_mut(); }
2694    };
2695    let _ = env.set_long_array_region(&array, 0, &ptrs);
2696
2697    array.into_raw()
2698}
2699
2700#[no_mangle]
2701pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_disableProvider0(
2702    mut env: JNIEnv,
2703    _class: JClass,
2704    ptr: jlong,
2705    provider_id: JString,
2706) -> jboolean {
2707    if !check_not_null(&mut env, ptr, "RiOAuthManager") {
2708        return 0;
2709    }
2710
2711    let manager = unsafe { &*(ptr as *const RiOAuthManager) };
2712    let provider_id_str: String = match env.get_string(&provider_id) {
2713        Ok(s) => s.into(),
2714        Err(_) => {
2715            crate::java::exception::throw_ri_error(&mut env, "Failed to get provider_id");
2716            return 0;
2717        }
2718    };
2719
2720    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.disable_provider(&provider_id_str).await }) {
2721        Some(Ok(result)) => {
2722            if result {
2723                1
2724            } else {
2725                0
2726            }
2727        }
2728        _ => 0,
2729    }
2730}
2731
2732#[no_mangle]
2733pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_enableProvider0(
2734    mut env: JNIEnv,
2735    _class: JClass,
2736    ptr: jlong,
2737    provider_id: JString,
2738) -> jboolean {
2739    if !check_not_null(&mut env, ptr, "RiOAuthManager") {
2740        return 0;
2741    }
2742
2743    let manager = unsafe { &*(ptr as *const RiOAuthManager) };
2744    let provider_id_str: String = match env.get_string(&provider_id) {
2745        Ok(s) => s.into(),
2746        Err(_) => {
2747            crate::java::exception::throw_ri_error(&mut env, "Failed to get provider_id");
2748            return 0;
2749        }
2750    };
2751
2752    match crate::java::runtime::block_on_local(&mut env, "RiAuth", async { manager.enable_provider(&provider_id_str).await }) {
2753        Some(Ok(result)) => {
2754            if result {
2755                1
2756            } else {
2757                0
2758            }
2759        }
2760        _ => 0,
2761    }
2762}
2763
2764#[no_mangle]
2765pub extern "system" fn Java_com_dunimd_ri_auth_RiOAuthManager_free0(
2766    _env: JNIEnv,
2767    _class: JClass,
2768    ptr: jlong,
2769) {
2770    if ptr != 0 {
2771        unsafe {
2772            let _ = Box::from_raw(ptr as *mut RiOAuthManager);
2773        }
2774    }
2775}
2776
2777// =============================================================================
2778// RiRevokedTokenInfo JNI Bindings
2779// =============================================================================
2780
2781#[no_mangle]
2782pub extern "system" fn Java_com_dunimd_ri_auth_RiRevokedTokenInfo_new0(
2783    mut env: JNIEnv,
2784    _class: JClass,
2785    token_id: JString,
2786    user_id: JString,
2787    revoked_at: jlong,
2788    expires_at: jlong,
2789    reason: JString,
2790) -> jlong {
2791    let token_id_str: String = match env.get_string(&token_id) {
2792        Ok(s) => s.into(),
2793        Err(_) => {
2794            crate::java::exception::throw_ri_error(&mut env, "Failed to get token_id");
2795            return 0;
2796        }
2797    };
2798    let user_id_str: String = match env.get_string(&user_id) {
2799        Ok(s) => s.into(),
2800        Err(_) => {
2801            crate::java::exception::throw_ri_error(&mut env, "Failed to get user_id");
2802            return 0;
2803        }
2804    };
2805    let reason_opt = if reason.is_null() {
2806        None
2807    } else {
2808        env.get_string(&reason).ok().map(|s| s.into())
2809    };
2810
2811    let info = Box::new(RiRevokedTokenInfo {
2812        token_id: token_id_str,
2813        user_id: user_id_str,
2814        revoked_at: revoked_at as u64,
2815        expires_at: expires_at as u64,
2816        reason: reason_opt,
2817    });
2818    Box::into_raw(info) as jlong
2819}
2820
2821#[no_mangle]
2822pub extern "system" fn Java_com_dunimd_ri_auth_RiRevokedTokenInfo_getTokenId0(
2823    mut env: JNIEnv,
2824    _class: JClass,
2825    ptr: jlong,
2826) -> jstring {
2827    if !check_not_null(&mut env, ptr, "RiRevokedTokenInfo") {
2828        return std::ptr::null_mut();
2829    }
2830
2831    let info = unsafe { &*(ptr as *const RiRevokedTokenInfo) };
2832    match env.new_string(&info.token_id) {
2833        Ok(s) => s.into_raw(),
2834        Err(_) => std::ptr::null_mut(),
2835    }
2836}
2837
2838#[no_mangle]
2839pub extern "system" fn Java_com_dunimd_ri_auth_RiRevokedTokenInfo_getUserId0(
2840    mut env: JNIEnv,
2841    _class: JClass,
2842    ptr: jlong,
2843) -> jstring {
2844    if !check_not_null(&mut env, ptr, "RiRevokedTokenInfo") {
2845        return std::ptr::null_mut();
2846    }
2847
2848    let info = unsafe { &*(ptr as *const RiRevokedTokenInfo) };
2849    match env.new_string(&info.user_id) {
2850        Ok(s) => s.into_raw(),
2851        Err(_) => std::ptr::null_mut(),
2852    }
2853}
2854
2855#[no_mangle]
2856pub extern "system" fn Java_com_dunimd_ri_auth_RiRevokedTokenInfo_getRevokedAt0(
2857    mut env: JNIEnv,
2858    _class: JClass,
2859    ptr: jlong,
2860) -> jlong {
2861    if !check_not_null(&mut env, ptr, "RiRevokedTokenInfo") {
2862        return 0;
2863    }
2864
2865    let info = unsafe { &*(ptr as *const RiRevokedTokenInfo) };
2866    info.revoked_at as jlong
2867}
2868
2869#[no_mangle]
2870pub extern "system" fn Java_com_dunimd_ri_auth_RiRevokedTokenInfo_getExpiresAt0(
2871    mut env: JNIEnv,
2872    _class: JClass,
2873    ptr: jlong,
2874) -> jlong {
2875    if !check_not_null(&mut env, ptr, "RiRevokedTokenInfo") {
2876        return 0;
2877    }
2878
2879    let info = unsafe { &*(ptr as *const RiRevokedTokenInfo) };
2880    info.expires_at as jlong
2881}
2882
2883#[no_mangle]
2884pub extern "system" fn Java_com_dunimd_ri_auth_RiRevokedTokenInfo_getReason0(
2885    mut env: JNIEnv,
2886    _class: JClass,
2887    ptr: jlong,
2888) -> jstring {
2889    if !check_not_null(&mut env, ptr, "RiRevokedTokenInfo") {
2890        return std::ptr::null_mut();
2891    }
2892
2893    let info = unsafe { &*(ptr as *const RiRevokedTokenInfo) };
2894    match &info.reason {
2895        Some(r) => match env.new_string(r) {
2896        Ok(s) => s.into_raw(),
2897        Err(_) => std::ptr::null_mut(),
2898    },
2899        None => std::ptr::null_mut(),
2900    }
2901}
2902
2903#[no_mangle]
2904pub extern "system" fn Java_com_dunimd_ri_auth_RiRevokedTokenInfo_free0(
2905    _env: JNIEnv,
2906    _class: JClass,
2907    ptr: jlong,
2908) {
2909    if ptr != 0 {
2910        unsafe {
2911            let _ = Box::from_raw(ptr as *mut RiRevokedTokenInfo);
2912        }
2913    }
2914}
2915
2916// =============================================================================
2917// RiJWTRevocationList JNI Bindings
2918// =============================================================================
2919
2920#[no_mangle]
2921pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTRevocationList_new0(
2922    _env: JNIEnv,
2923    _class: JClass,
2924) -> jlong {
2925    let list = Box::new(RiJWTRevocationList::new());
2926    Box::into_raw(list) as jlong
2927}
2928
2929#[no_mangle]
2930pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTRevocationList_revokeToken0(
2931    mut env: JNIEnv,
2932    _class: JClass,
2933    ptr: jlong,
2934    token: JString,
2935    user_id: JString,
2936    reason: JString,
2937    ttl_secs: jlong,
2938) {
2939    if !check_not_null(&mut env, ptr, "RiJWTRevocationList") {
2940        return;
2941    }
2942
2943    let list = unsafe { &*(ptr as *const RiJWTRevocationList) };
2944    let token_str: String = match env.get_string(&token) {
2945        Ok(s) => s.into(),
2946        Err(_) => {
2947            crate::java::exception::throw_ri_error(&mut env, "Failed to get token");
2948            return;
2949        }
2950    };
2951    let user_id_str: String = match env.get_string(&user_id) {
2952        Ok(s) => s.into(),
2953        Err(_) => {
2954            crate::java::exception::throw_ri_error(&mut env, "Failed to get user_id");
2955            return;
2956        }
2957    };
2958    let reason_opt = if reason.is_null() {
2959        None
2960    } else {
2961        env.get_string(&reason).ok().map(|s| s.into())
2962    };
2963
2964    list.revoke_token(&token_str, &user_id_str, reason_opt, ttl_secs as u64);
2965}
2966
2967#[no_mangle]
2968pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTRevocationList_isRevoked0(
2969    mut env: JNIEnv,
2970    _class: JClass,
2971    ptr: jlong,
2972    token: JString,
2973) -> jboolean {
2974    if !check_not_null(&mut env, ptr, "RiJWTRevocationList") {
2975        return 0;
2976    }
2977
2978    let list = unsafe { &*(ptr as *const RiJWTRevocationList) };
2979    let token_str: String = match env.get_string(&token) {
2980        Ok(s) => s.into(),
2981        Err(_) => {
2982            crate::java::exception::throw_ri_error(&mut env, "Failed to get token");
2983            return 0;
2984        }
2985    };
2986
2987    if list.is_revoked(&token_str) {
2988        1
2989    } else {
2990        0
2991    }
2992}
2993
2994#[no_mangle]
2995pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTRevocationList_revokeByUser0(
2996    mut env: JNIEnv,
2997    _class: JClass,
2998    ptr: jlong,
2999    user_id: JString,
3000) -> jboolean {
3001    if !check_not_null(&mut env, ptr, "RiJWTRevocationList") {
3002        return 0;
3003    }
3004
3005    let list = unsafe { &*(ptr as *const RiJWTRevocationList) };
3006    let user_id_str: String = match env.get_string(&user_id) {
3007        Ok(s) => s.into(),
3008        Err(_) => {
3009            crate::java::exception::throw_ri_error(&mut env, "Failed to get user_id");
3010            return 0;
3011        }
3012    };
3013
3014    let count = list.revoke_all_user_tokens(&user_id_str, None);
3015    if count > 0 {
3016        1
3017    } else {
3018        0
3019    }
3020}
3021
3022#[no_mangle]
3023pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTRevocationList_getRevocationInfo0(
3024    mut env: JNIEnv,
3025    _class: JClass,
3026    ptr: jlong,
3027    token: JString,
3028) -> jlong {
3029    if !check_not_null(&mut env, ptr, "RiJWTRevocationList") {
3030        return 0;
3031    }
3032
3033    let list = unsafe { &*(ptr as *const RiJWTRevocationList) };
3034    let token_str: String = match env.get_string(&token) {
3035        Ok(s) => s.into(),
3036        Err(_) => {
3037            crate::java::exception::throw_ri_error(&mut env, "Failed to get token");
3038            return 0;
3039        }
3040    };
3041
3042    match list.get_revocation_info(&token_str) {
3043        Some(info) => {
3044            let info_box = Box::new(info);
3045            Box::into_raw(info_box) as jlong
3046        }
3047        None => 0,
3048    }
3049}
3050
3051#[no_mangle]
3052pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTRevocationList_getRevokedCount0(
3053    mut env: JNIEnv,
3054    _class: JClass,
3055    ptr: jlong,
3056) -> jint {
3057    if !check_not_null(&mut env, ptr, "RiJWTRevocationList") {
3058        return 0;
3059    }
3060
3061    let list = unsafe { &*(ptr as *const RiJWTRevocationList) };
3062    list.get_revoked_count() as jint
3063}
3064
3065#[no_mangle]
3066pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTRevocationList_cleanup0(
3067    mut env: JNIEnv,
3068    _class: JClass,
3069    ptr: jlong,
3070) -> jint {
3071    if !check_not_null(&mut env, ptr, "RiJWTRevocationList") {
3072        return 0;
3073    }
3074
3075    let list = unsafe { &*(ptr as *const RiJWTRevocationList) };
3076    list.cleanup() as jint
3077}
3078
3079#[no_mangle]
3080pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTRevocationList_clear0(
3081    mut env: JNIEnv,
3082    _class: JClass,
3083    ptr: jlong,
3084) {
3085    if !check_not_null(&mut env, ptr, "RiJWTRevocationList") {
3086        return;
3087    }
3088
3089    let list = unsafe { &*(ptr as *const RiJWTRevocationList) };
3090    list.clear();
3091}
3092
3093#[no_mangle]
3094pub extern "system" fn Java_com_dunimd_ri_auth_RiJWTRevocationList_free0(
3095    _env: JNIEnv,
3096    _class: JClass,
3097    ptr: jlong,
3098) {
3099    if ptr != 0 {
3100        unsafe {
3101            let _ = Box::from_raw(ptr as *mut RiJWTRevocationList);
3102        }
3103    }
3104}
3105
3106// =============================================================================
3107// RiSecurityManager JNI Bindings (Static Methods)
3108// =============================================================================
3109
3110#[no_mangle]
3111pub extern "system" fn Java_com_dunimd_ri_auth_RiSecurityManager_encrypt0(
3112    mut env: JNIEnv,
3113    _class: JClass,
3114    plaintext: JString,
3115) -> jstring {
3116    let plaintext_str: String = match env.get_string(&plaintext) {
3117        Ok(s) => s.into(),
3118        Err(_) => {
3119            crate::java::exception::throw_ri_error(&mut env, "Failed to get plaintext");
3120            return std::ptr::null_mut();
3121        }
3122    };
3123
3124    match RiSecurityManager::encrypt(&plaintext_str) {
3125        Ok(encrypted) => match env.new_string(&encrypted) {
3126        Ok(s) => s.into_raw(),
3127        Err(_) => std::ptr::null_mut(),
3128    },
3129        Err(_) => std::ptr::null_mut(),
3130    }
3131}
3132
3133#[no_mangle]
3134pub extern "system" fn Java_com_dunimd_ri_auth_RiSecurityManager_decrypt0(
3135    mut env: JNIEnv,
3136    _class: JClass,
3137    encrypted: JString,
3138) -> jstring {
3139    let encrypted_str: String = match env.get_string(&encrypted) {
3140        Ok(s) => s.into(),
3141        Err(_) => {
3142            crate::java::exception::throw_ri_error(&mut env, "Failed to get encrypted");
3143            return std::ptr::null_mut();
3144        }
3145    };
3146
3147    match RiSecurityManager::decrypt(&encrypted_str) {
3148        Ok(decrypted) => match env.new_string(&decrypted) {
3149        Ok(s) => s.into_raw(),
3150        Err(_) => std::ptr::null_mut(),
3151    },
3152        Err(_) => std::ptr::null_mut(),
3153    }
3154}
3155
3156#[no_mangle]
3157pub extern "system" fn Java_com_dunimd_ri_auth_RiSecurityManager_hmacSign0(
3158    mut env: JNIEnv,
3159    _class: JClass,
3160    data: JString,
3161) -> jstring {
3162    let data_str: String = match env.get_string(&data) {
3163        Ok(s) => s.into(),
3164        Err(_) => {
3165            crate::java::exception::throw_ri_error(&mut env, "Failed to get data");
3166            return std::ptr::null_mut();
3167        }
3168    };
3169
3170    let signature = RiSecurityManager::hmac_sign(&data_str);
3171    match env.new_string(&signature) {
3172        Ok(s) => s.into_raw(),
3173        Err(_) => std::ptr::null_mut(),
3174    }
3175}
3176
3177#[no_mangle]
3178pub extern "system" fn Java_com_dunimd_ri_auth_RiSecurityManager_hmacVerify0(
3179    mut env: JNIEnv,
3180    _class: JClass,
3181    data: JString,
3182    signature: JString,
3183) -> jboolean {
3184    let data_str: String = match env.get_string(&data) {
3185        Ok(s) => s.into(),
3186        Err(_) => {
3187            crate::java::exception::throw_ri_error(&mut env, "Failed to get data");
3188            return 0;
3189        }
3190    };
3191    let signature_str: String = match env.get_string(&signature) {
3192        Ok(s) => s.into(),
3193        Err(_) => {
3194            crate::java::exception::throw_ri_error(&mut env, "Failed to get signature");
3195            return 0;
3196        }
3197    };
3198
3199    if RiSecurityManager::hmac_verify(&data_str, &signature_str) {
3200        1
3201    } else {
3202        0
3203    }
3204}
3205
3206#[no_mangle]
3207pub extern "system" fn Java_com_dunimd_ri_auth_RiSecurityManager_generateEncryptionKey0(
3208    env: JNIEnv,
3209    _class: JClass,
3210) -> jstring {
3211    let key = RiSecurityManager::generate_encryption_key();
3212    match env.new_string(&key) {
3213        Ok(s) => s.into_raw(),
3214        Err(_) => std::ptr::null_mut(),
3215    }
3216}
3217
3218#[no_mangle]
3219pub extern "system" fn Java_com_dunimd_ri_auth_RiSecurityManager_generateHmacKey0(
3220    env: JNIEnv,
3221    _class: JClass,
3222) -> jstring {
3223    let key = RiSecurityManager::generate_hmac_key();
3224    match env.new_string(&key) {
3225        Ok(s) => s.into_raw(),
3226        Err(_) => std::ptr::null_mut(),
3227    }
3228}