@@ -5,51 +5,243 @@ use crate::grpc::backend::education_set_server::*;
5
5
use crate :: grpc:: backend:: * ;
6
6
7
7
use entity:: { education:: * , * } ;
8
+
9
+ impl Filter for Entity {
10
+ fn write_filter < S : QueryFilter + Send > ( query : S , auth : & Auth ) -> Result < S , Error > {
11
+ let ( user_id, perm) = auth. ok_or_default ( ) ?;
12
+ if perm. can_root ( ) {
13
+ return Ok ( query) ;
14
+ }
15
+ if perm. can_manage_education ( ) {
16
+ return Ok ( query. filter ( education:: Column :: UserId . eq ( user_id) ) ) ;
17
+ }
18
+ Err ( Error :: Unauthenticated )
19
+ }
20
+ }
21
+
8
22
#[ async_trait]
9
- impl EducationSet for Arc < Server > {
10
- async fn list (
11
- & self ,
12
- req : Request < ListRequest > ,
13
- ) -> Result < Response < ListEducationResponse > , Status > {
14
- Err ( Status :: unimplemented ( "unimplemented" ) )
23
+ impl ParentalFilter for Entity {
24
+ fn publish_filter < S : QueryFilter + Send > ( query : S , auth : & Auth ) -> Result < S , Error > {
25
+ if let Some ( perm) = auth. user_perm ( ) {
26
+ if perm. can_root ( ) {
27
+ return Ok ( query) ;
28
+ }
29
+ if perm. can_publish ( ) {
30
+ let user_id = auth. user_id ( ) . unwrap ( ) ;
31
+ return Ok ( query. filter ( Column :: UserId . eq ( user_id) ) ) ;
32
+ }
33
+ }
34
+ Err ( Error :: PremissionDeny ( "Can't publish education" ) )
15
35
}
16
- async fn search_by_text (
17
- & self ,
18
- req : Request < TextSearchRequest > ,
19
- ) -> Result < Response < ListEducationResponse > , Status > {
20
- Err ( Status :: unimplemented ( "unimplemented" ) )
36
+
37
+ fn link_filter < S : QueryFilter + Send > ( query : S , auth : & Auth ) -> Result < S , Error > {
38
+ if let Some ( perm) = auth. user_perm ( ) {
39
+ if perm. can_root ( ) {
40
+ return Ok ( query) ;
41
+ }
42
+ if perm. can_link ( ) {
43
+ let user_id = auth. user_id ( ) . unwrap ( ) ;
44
+ return Ok ( query. filter ( Column :: UserId . eq ( user_id) ) ) ;
45
+ }
46
+ }
47
+ Err ( Error :: PremissionDeny ( "Can't link education" ) )
21
48
}
22
- async fn search_by_tag (
23
- & self ,
24
- req : Request < TextSearchRequest > ,
25
- ) -> Result < Response < ListEducationResponse > , Status > {
26
- Err ( Status :: unimplemented ( "unimplemented" ) )
49
+ }
50
+
51
+ impl From < i32 > for EducationId {
52
+ fn from ( value : i32 ) -> Self {
53
+ Self { id : value }
27
54
}
28
- async fn full_info (
29
- & self ,
30
- req : Request < EducationId > ,
31
- ) -> Result < Response < EducationFullInfo > , Status > {
32
- Err ( Status :: unimplemented ( "unimplemented" ) )
55
+ }
56
+
57
+ impl From < EducationId > for i32 {
58
+ fn from ( value : EducationId ) -> Self {
59
+ value . id
33
60
}
34
- async fn create ( & self , req : Request < CreateEducationRequest > ) -> Result < Response < ( ) > , Status > {
35
- Err ( Status :: unimplemented ( "unimplemented" ) )
61
+ }
62
+
63
+ impl From < Model > for EducationFullInfo {
64
+ fn from ( value : Model ) -> Self {
65
+ todo ! ( )
66
+ }
67
+ }
68
+ impl From < Model > for EducationInfo {
69
+ fn from ( value : Model ) -> Self {
70
+ todo ! ( )
71
+ }
72
+ }
73
+
74
+ #[ async_trait]
75
+ impl EducationSet for Arc < Server > {
76
+ async fn create (
77
+ & self ,
78
+ req : Request < CreateEducationRequest > ,
79
+ ) -> Result < Response < EducationId > , Status > {
80
+ let db = DB . get ( ) . unwrap ( ) ;
81
+ let ( auth, req) = self . parse_request ( req) . await ?;
82
+ let ( user_id, perm) = auth. ok_or_default ( ) ?;
83
+
84
+ let uuid = Uuid :: parse_str ( & req. request_id ) . map_err ( Error :: InvaildUUID ) ?;
85
+ if let Some ( x) = self . dup . check ( user_id, & uuid) {
86
+ return Ok ( Response :: new ( x. into ( ) ) ) ;
87
+ } ;
88
+
89
+ if !( perm. can_root ( ) || perm. can_manage_problem ( ) ) {
90
+ return Err ( Error :: PremissionDeny ( "Can't create education" ) . into ( ) ) ;
91
+ }
92
+
93
+ let mut model: ActiveModel = Default :: default ( ) ;
94
+ model. user_id = ActiveValue :: Set ( user_id) ;
95
+
96
+ fill_active_model ! ( model, req. info, title, content) ;
97
+
98
+ let model = model. save ( db) . await . map_err ( Into :: < Error > :: into) ?;
99
+
100
+ self . dup . store ( user_id, uuid, model. id . clone ( ) . unwrap ( ) ) ;
101
+
102
+ Ok ( Response :: new ( model. id . unwrap ( ) . into ( ) ) )
36
103
}
37
104
async fn update ( & self , req : Request < UpdateEducationRequest > ) -> Result < Response < ( ) > , Status > {
38
- Err ( Status :: unimplemented ( "unimplemented" ) )
105
+ let db = DB . get ( ) . unwrap ( ) ;
106
+ let ( auth, req) = self . parse_request ( req) . await ?;
107
+
108
+ let ( user_id, perm) = auth. ok_or_default ( ) ?;
109
+
110
+ let uuid = Uuid :: parse_str ( & req. request_id ) . map_err ( Error :: InvaildUUID ) ?;
111
+ if self . dup . check ( user_id, & uuid) . is_some ( ) {
112
+ return Ok ( Response :: new ( ( ) ) ) ;
113
+ } ;
114
+
115
+ if !( perm. can_root ( ) || perm. can_manage_problem ( ) ) {
116
+ return Err ( Error :: PremissionDeny ( "Can't update problem" ) . into ( ) ) ;
117
+ }
118
+
119
+ let mut model = Entity :: write_filter ( Entity :: find_by_id ( req. id ) , & auth) ?
120
+ . one ( db)
121
+ . await
122
+ . map_err ( Into :: < Error > :: into) ?
123
+ . ok_or ( Error :: NotInDB ( "problem" ) ) ?
124
+ . into_active_model ( ) ;
125
+
126
+ fill_exist_active_model ! ( model, req. info, title, content) ;
127
+
128
+ let model = model. update ( db) . await . map_err ( Into :: < Error > :: into) ?;
129
+
130
+ self . dup . store ( user_id, uuid, model. id ) ;
131
+
132
+ Ok ( Response :: new ( ( ) ) )
39
133
}
40
134
async fn remove ( & self , req : Request < EducationId > ) -> Result < Response < ( ) > , Status > {
41
- Err ( Status :: unimplemented ( "unimplemented" ) )
135
+ let db = DB . get ( ) . unwrap ( ) ;
136
+ let ( auth, req) = self . parse_request ( req) . await ?;
137
+
138
+ Entity :: write_filter ( Entity :: delete_by_id ( Into :: < i32 > :: into ( req. id ) ) , & auth) ?
139
+ . exec ( db)
140
+ . await
141
+ . map_err ( Into :: < Error > :: into) ?;
142
+
143
+ Ok ( Response :: new ( ( ) ) )
42
144
}
43
145
async fn link ( & self , req : Request < EducationLink > ) -> Result < Response < ( ) > , Status > {
44
- Err ( Status :: unimplemented ( "unimplemented" ) )
146
+ let db = DB . get ( ) . unwrap ( ) ;
147
+ let ( auth, req) = self . parse_request ( req) . await ?;
148
+
149
+ let ( _, perm) = auth. ok_or_default ( ) ?;
150
+
151
+ if !( perm. can_root ( ) || perm. can_link ( ) ) {
152
+ return Err ( Error :: PremissionDeny ( "Can't link problem" ) . into ( ) ) ;
153
+ }
154
+
155
+ let mut model = Entity :: link_filter ( Entity :: find_by_id ( req. problem_id . id ) , & auth) ?
156
+ . columns ( [ Column :: Id , Column :: ProblemId ] )
157
+ . one ( db)
158
+ . await
159
+ . map_err ( Into :: < Error > :: into) ?
160
+ . ok_or ( Error :: NotInDB ( "problem" ) ) ?
161
+ . into_active_model ( ) ;
162
+
163
+ model. problem_id = ActiveValue :: Set ( Some ( req. problem_id . id ) ) ;
164
+
165
+ model. save ( db) . await . map_err ( Into :: < Error > :: into) ?;
166
+
167
+ Ok ( Response :: new ( ( ) ) )
45
168
}
46
169
async fn unlink ( & self , req : Request < EducationLink > ) -> Result < Response < ( ) > , Status > {
47
- Err ( Status :: unimplemented ( "unimplemented" ) )
170
+ let db = DB . get ( ) . unwrap ( ) ;
171
+ let ( auth, req) = self . parse_request ( req) . await ?;
172
+
173
+ let ( _, perm) = auth. ok_or_default ( ) ?;
174
+
175
+ if !( perm. can_root ( ) || perm. can_link ( ) ) {
176
+ return Err ( Error :: PremissionDeny ( "Can't link problem" ) . into ( ) ) ;
177
+ }
178
+
179
+ let mut model = Entity :: link_filter ( Entity :: find_by_id ( req. problem_id . id ) , & auth) ?
180
+ . columns ( [ Column :: Id , Column :: ProblemId ] )
181
+ . one ( db)
182
+ . await
183
+ . map_err ( Into :: < Error > :: into) ?
184
+ . ok_or ( Error :: NotInDB ( "problem" ) ) ?
185
+ . into_active_model ( ) ;
186
+
187
+ model. problem_id = ActiveValue :: Set ( None ) ;
188
+
189
+ model. save ( db) . await . map_err ( Into :: < Error > :: into) ?;
190
+
191
+ Ok ( Response :: new ( ( ) ) )
192
+ }
193
+
194
+ async fn list_by_problem (
195
+ & self ,
196
+ req : Request < ListByRequest > ,
197
+ ) -> Result < Response < ListEducationResponse > , Status > {
198
+ let ( auth, req) = self . parse_request ( req) . await ?;
199
+
200
+ let mut reverse = false ;
201
+ let mut pager: Pager < Entity > = match req. request . ok_or ( Error :: NotInPayload ( "request" ) ) ? {
202
+ list_by_request:: Request :: ParentId ( ppk) => Pager :: parent_search ( ppk) ,
203
+ list_by_request:: Request :: Pager ( old) => {
204
+ reverse = old. reverse ;
205
+ <Pager < Entity > as HasParentPager < problem:: Entity , Entity > >:: from_raw ( old. session ) ?
206
+ }
207
+ } ;
208
+
209
+ let list = pager
210
+ . fetch ( req. size , req. offset . unwrap_or_default ( ) , reverse, & auth)
211
+ . await ?
212
+ . into_iter ( )
213
+ . map ( |x| x. into ( ) )
214
+ . collect ( ) ;
215
+
216
+ let next_session = pager. into_raw ( ) ;
217
+
218
+ Ok ( Response :: new ( ListEducationResponse { list, next_session } ) )
48
219
}
49
220
async fn full_info_by_problem (
50
221
& self ,
51
222
req : Request < EducationLink > ,
52
223
) -> Result < Response < EducationFullInfo > , Status > {
53
- Err ( Status :: unimplemented ( "unimplemented" ) )
224
+ let db = DB . get ( ) . unwrap ( ) ;
225
+ let ( auth, req) = self . parse_request ( req) . await ?;
226
+
227
+ let parent = auth
228
+ . get_user ( db)
229
+ . await ?
230
+ . find_related ( problem:: Entity )
231
+ . columns ( [ contest:: Column :: Id ] )
232
+ . one ( db)
233
+ . await
234
+ . map_err ( Into :: < Error > :: into) ?
235
+ . ok_or ( Error :: NotInDB ( "problem" ) ) ?;
236
+
237
+ let model = parent
238
+ . find_related ( Entity )
239
+ . filter ( Column :: Id . eq ( Into :: < i32 > :: into ( req. problem_id ) ) )
240
+ . one ( db)
241
+ . await
242
+ . map_err ( Into :: < Error > :: into) ?
243
+ . ok_or ( Error :: NotInDB ( "education" ) ) ?;
244
+
245
+ Ok ( Response :: new ( model. into ( ) ) )
54
246
}
55
247
}
0 commit comments