db_objects.rs 8.09 KB
Newer Older
1
2
extern crate time;

Robert Czechowski's avatar
Robert Czechowski committed
3
use self::time::{Duration, Timespec};
4

5
#[derive(Clone)]
6
pub struct SessionUser {
7
    pub id: i32,
8
9
10
11
12
    pub session_token: Option<String>, // delete this to log out
    pub csrf_token: String,
    pub last_login: Option<Timespec>,
    pub last_activity: Option<Timespec>,
    pub permanent_login: bool,
Robert Czechowski's avatar
Robert Czechowski committed
13

14
15
    pub username: Option<String>,
    pub password: Option<String>,
Robert Czechowski's avatar
Robert Czechowski committed
16
    pub salt: Option<String>,
17
18
19
20
21
22
23
24
25
26
27
    pub logincode: Option<String>,
    pub email: Option<String>,
    pub email_unconfirmed: Option<String>,
    pub email_confirmationcode: Option<String>,

    pub firstname: Option<String>,
    pub lastname: Option<String>,
    pub street: Option<String>,
    pub zip: Option<String>,
    pub city: Option<String>,
    pub nation: Option<String>,
28
    pub grade: i32,
29
    pub sex: Option<i32>,
30
31

    pub is_teacher: bool,
32
    pub managed_by: Option<i32>,
33
34
35
36
37

    pub oauth_foreign_id: Option<String>,
    pub oauth_provider: Option<String>,
    // pub oauth_extra_data: Option<String>,

38
39
    // pub pms_id: Option<i32>,
    // pub pms_school_id: Option<i32>,
40
41
}

42
43
44
// Short version for display
#[derive(Clone, Default)]
pub struct UserInfo {
45
    pub id: i32,
46
47
48
49
    pub username: Option<String>,
    pub logincode: Option<String>,
    pub firstname: Option<String>,
    pub lastname: Option<String>,
50
    pub grade: i32,
51
52
53
}

#[derive(Clone)]
Robert Czechowski's avatar
Robert Czechowski committed
54
pub struct Group {
55
    pub id: Option<i32>,
Robert Czechowski's avatar
Robert Czechowski committed
56
57
58
    pub name: String,
    pub groupcode: String,
    pub tag: String,
59
    pub admin: i32,
Robert Czechowski's avatar
Robert Czechowski committed
60
    pub members: Vec<SessionUser>,
Robert Czechowski's avatar
Robert Czechowski committed
61
62
}

63
#[derive(Debug)]
64
pub struct Contest {
65
    pub id: Option<i32>,
66
67
68
    pub location: String,
    pub filename: String,
    pub name: String,
69
    pub duration: i32,
70
71
72
    pub public: bool,
    pub start: Option<Timespec>,
    pub end: Option<Timespec>,
73
74
    pub min_grade: Option<i32>,
    pub max_grade: Option<i32>,
75
    pub positionalnumber: Option<i32>,
76
77
    pub requires_login: Option<bool>,
    pub secret: Option<String>,
78
79
80
    pub taskgroups: Vec<Taskgroup>,
}

81
#[derive(Debug)]
82
pub struct Taskgroup {
83
84
    pub id: Option<i32>,
    pub contest: i32,
85
    pub name: String,
86
    pub active: bool,
87
    pub positionalnumber: Option<i32>,
88
89
90
    pub tasks: Vec<Task>,
}

91
#[derive(Debug)]
92
pub struct Task {
93
94
    pub id: Option<i32>,
    pub taskgroup: i32,
95
    pub location: String,
96
    pub stars: i32,
97
98
99
}

pub struct Submission {
100
101
102
103
    pub id: Option<i32>,
    pub session_user: i32,
    pub task: i32,
    pub grade: i32,
Robert Czechowski's avatar
Robert Czechowski committed
104
    pub validated: bool,
105
    pub nonvalidated_grade: i32,
Robert Czechowski's avatar
Robert Czechowski committed
106
107
108
109
    pub needs_validation: bool,
    pub subtask_identifier: Option<String>,
    pub value: String,
    pub date: Timespec,
110
111
}

112
#[derive(Clone, Copy, Default, Debug)]
113
pub struct Grade {
114
115
116
    pub taskgroup: i32,
    pub user: i32,
    pub grade: Option<i32>,
117
118
119
120
    pub validated: bool,
}

pub struct Participation {
121
122
    pub contest: i32,
    pub user: i32,
123
124
125
    pub start: Timespec,
}

Robert Czechowski's avatar
Robert Czechowski committed
126
pub trait HasId {
127
128
    fn get_id(&self) -> Option<i32>;
    fn set_id(&mut self, id: i32);
Robert Czechowski's avatar
Robert Czechowski committed
129
130
}
impl HasId for Submission {
131
132
    fn get_id(&self) -> Option<i32> { self.id }
    fn set_id(&mut self, id: i32) { self.id = Some(id); }
Robert Czechowski's avatar
Robert Czechowski committed
133
134
}
impl HasId for Task {
135
136
    fn get_id(&self) -> Option<i32> { self.id }
    fn set_id(&mut self, id: i32) { self.id = Some(id); }
Robert Czechowski's avatar
Robert Czechowski committed
137
138
}
impl HasId for Taskgroup {
139
140
    fn get_id(&self) -> Option<i32> { self.id }
    fn set_id(&mut self, id: i32) { self.id = Some(id); }
Robert Czechowski's avatar
Robert Czechowski committed
141
142
}
impl HasId for Contest {
143
144
    fn get_id(&self) -> Option<i32> { self.id }
    fn set_id(&mut self, id: i32) { self.id = Some(id); }
Robert Czechowski's avatar
Robert Czechowski committed
145
146
}
impl HasId for Group {
147
148
    fn get_id(&self) -> Option<i32> { self.id }
    fn set_id(&mut self, id: i32) { self.id = Some(id); }
Robert Czechowski's avatar
Robert Czechowski committed
149
}
150
151

impl Contest {
152
153
    // TODO: Rewrite, so this attribute can be removed
    #[allow(clippy::too_many_arguments)]
154
    pub fn new(location: String, filename: String, name: String, duration: i32, public: bool,
155
               start: Option<Timespec>, end: Option<Timespec>, min_grade: Option<i32>, max_grade: Option<i32>,
156
               positionalnumber: Option<i32>, requires_login: Option<bool>, secret: Option<String>)
Robert Czechowski's avatar
Robert Czechowski committed
157
158
159
160
161
162
163
164
165
166
               -> Self
    {
        Contest { id: None,
                  location: location,
                  filename: filename,
                  name: name,
                  duration: duration,
                  public: public,
                  start: start,
                  end: end,
167
168
                  min_grade: min_grade,
                  max_grade: max_grade,
169
                  positionalnumber: positionalnumber,
170
171
                  requires_login: requires_login,
                  secret: secret,
Robert Czechowski's avatar
Robert Czechowski committed
172
173
                  taskgroups: Vec::new() }
    }
174
175
176
}

impl SessionUser {
177
    pub fn minimal(id: i32, session_token: String, csrf_token: String) -> Self {
Robert Czechowski's avatar
rustfmt    
Robert Czechowski committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
        SessionUser {
            id: id,
            session_token: Some(session_token),
            csrf_token: csrf_token,
            last_login: None,
            last_activity: None, // now?
            // müssen die überhaupt außerhalb der datenbankabstraktion sichtbar sein?
            permanent_login: false,

            username: None,
            password: None,
            salt: None,
            logincode: None,
            email: None,
            email_unconfirmed: None,
            email_confirmationcode: None,

            firstname: None,
            lastname: None,
            street: None,
            zip: None,
            city: None,
            nation: None,
            grade: 0,
202
            sex: None,
Robert Czechowski's avatar
rustfmt    
Robert Czechowski committed
203
204
205
206
207
208
209
210
211
212

            is_teacher: false,
            managed_by: None,

            oauth_foreign_id: None,
            oauth_provider: None,
            // oauth_extra_data: Option<String>,

            //pms_id: None,
            //pms_school_id: None,
213
        }
214
    }
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
    pub fn group_user_stub() -> Self {
        SessionUser { id: 0,
                      session_token: None,
                      csrf_token: "".to_string(),
                      last_login: None,
                      last_activity: None,
                      permanent_login: false,

                      username: None,
                      password: None,
                      salt: None,
                      logincode: None,
                      email: None,
                      email_unconfirmed: None,
                      email_confirmationcode: None,

                      firstname: None,
                      lastname: None,
                      street: None,
                      zip: None,
                      city: None,
                      nation: None,
                      grade: 0,
239
                      sex: None,
240
241
242
243
244

                      is_teacher: false,
                      managed_by: None,

                      oauth_foreign_id: None,
Robert Czechowski's avatar
rustfmt    
Robert Czechowski committed
245
                      oauth_provider: None }
246
247
    }

248
    pub fn is_alive(&self) -> bool {
249
        let duration = if self.permanent_login { Duration::days(90) } else { Duration::hours(9) };
250
        let now = time::get_time();
251
252
253
254
255
256
257
258
        if let Some(last_activity) = self.last_activity {
            now - last_activity < duration
        } else {
            false
        }
    }

    pub fn is_logged_in(&self) -> bool {
259
        (self.password.is_some() || self.logincode.is_some() || self.oauth_foreign_id.is_some()) && self.is_alive()
260
261
262
263
    }

    pub fn ensure_alive(self) -> Option<Self> {
        if self.is_alive() {
264
            Some(self)
Robert Czechowski's avatar
Robert Czechowski committed
265
        } else {
266
            None
Robert Czechowski's avatar
Robert Czechowski committed
267
        }
268
269
270
    }

    pub fn ensure_logged_in(self) -> Option<Self> {
271
272
        if self.is_logged_in() {
            Some(self)
Robert Czechowski's avatar
Robert Czechowski committed
273
        } else {
274
275
276
            None
        }
    }
277
278
279
}

impl Taskgroup {
280
    pub fn new(name: String, positionalnumber: Option<i32>) -> Self {
281
282
283
284
285
286
        Taskgroup { id: None,
                    contest: 0,
                    name: name,
                    active: true,
                    positionalnumber: positionalnumber,
                    tasks: Vec::new() }
287
    }
288
289
290
}

impl Task {
291
    pub fn new(location: String, stars: i32) -> Self {
Robert Czechowski's avatar
Robert Czechowski committed
292
293
        Task { id: None, taskgroup: 0, location: location, stars: stars }
    }
294
}
295
296
297
298
299
300
301
302
303
304

pub trait OptionSession {
    fn ensure_alive(self) -> Self;
    fn ensure_logged_in(self) -> Self;
}

impl OptionSession for Option<SessionUser> {
    fn ensure_alive(self) -> Self { self?.ensure_alive() }
    fn ensure_logged_in(self) -> Self { self?.ensure_logged_in() }
}