diff --git a/API_Interfaces.txt b/API_Interfaces.txt index 825150a..2af2eaa 100644 --- a/API_Interfaces.txt +++ b/API_Interfaces.txt @@ -2,9 +2,25 @@ LoginAPI (api/login) ####################### POST -> Authentication method with login/password - login : User login - password : User password + In: + login : User login + password : User password + Out: + 200 -> AUTH_RESULT = "OK" : Authentication sucessful + 401 -> AUTH_RESULT = "AUTHENTICATION_FAILURE" : Wrong login/password + 403 -> AUTH_RESULT = "NOT_ALLOWED" : User is not allowed for this application + 201 -> AUTH_RESULT = "ALREADY_LOGGED" : A user is already logged on this session DELETE -> Logout current user + Out: + 200 -> AUTH_RESULT = "OK" : Logout sucessful + + +####################### +UserInfoAPI (api/userInfo) +####################### +GET -> Get the current logged user, return None if no one is connected + Out: + 200 -> USER = |None : Dictionary containing user infos or None diff --git a/backend/OLA.mysql b/backend/OLA.mysql index e64984d..7d5ac6f 100644 --- a/backend/OLA.mysql +++ b/backend/OLA.mysql @@ -23,14 +23,15 @@ CREATE TABLE IF NOT EXISTS SETTINGS CREATE TABLE IF NOT EXISTS `GROUP` ( - id BIGINT NOT NULL AUTO_INCREMENT, - `name` VARCHAR(128) NOT NULL UNIQUE, - `year` CHARACTER(4) NOT NULL, - class_short VARCHAR(128) NOT NULL, - class_long VARCHAR(512), - department VARCHAR(256), - resp_id BIGINT, - ressources_dir VARCHAR(512), + id BIGINT NOT NULL AUTO_INCREMENT, + `name` VARCHAR(128) NOT NULL UNIQUE, + `year` CHARACTER(4) NOT NULL, + class_short VARCHAR(128) NOT NULL, + class_long VARCHAR(512), + department VARCHAR(256), + resp_id BIGINT, + sec_id BIGINT, + ressources_dir VARCHAR(512), PRIMARY KEY(id) ) ENGINE = INNODB; @@ -96,7 +97,11 @@ CREATE TABLE IF NOT EXISTS HASHTABLE # Create FKs ALTER TABLE `GROUP` ADD FOREIGN KEY (resp_id) - REFERENCES `USER`(id) + REFERENCES `USER`(id); + +ALTER TABLE `GROUP` + ADD FOREIGN KEY (sec_id) +REFERENCES `USER` (id) ; ALTER TABLE TUTORSHIP diff --git a/backend/README.md b/backend/README.md index 6e98457..0d43c7a 100644 --- a/backend/README.md +++ b/backend/README.md @@ -26,6 +26,9 @@ python-tk pdftk libmagickwand-dev ``` +``` +apt install python-dev python-pip libtiff5-dev libjpeg8-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python-tk pdftk libmagickwand-dev +``` ## Python diff --git a/backend/app/api/UserInfoAPI.py b/backend/app/api/UserInfoAPI.py new file mode 100644 index 0000000..55f3625 --- /dev/null +++ b/backend/app/api/UserInfoAPI.py @@ -0,0 +1,12 @@ +from flask import session +from flask_restful import Resource + + +class UserInfoAPI(Resource): + """ + UserInfo Api Resource + """ + + def get(self): + user = session["user"] + return {'USER': user}, 200 diff --git a/backend/app/api/loginAPI.py b/backend/app/api/loginAPI.py index 0c049c5..d8ef502 100644 --- a/backend/app/api/loginAPI.py +++ b/backend/app/api/loginAPI.py @@ -2,7 +2,6 @@ from flask import session from flask_restful import Resource from flask_restful.reqparse import RequestParser -from app.core import cas from app.model import * @@ -12,6 +11,8 @@ class LoginAPI(Resource): """ def get(self): + if "user" in session and session["user"] is not None: + return {'AUTH_RESULT': 'ALREADY_LOGGED'}, 201 userInfo = self.getUserInfoFromCAS() if userInfo is not None: @@ -20,8 +21,10 @@ class LoginAPI(Resource): session['user'] = user return {'AUTH_RESULT': 'OK'}, 200 else: + session['user'] = None return {'AUTH_RESULT': 'NOT_ALLOWED'}, 403 else: + session['user'] = None return {'AUTH_RESULT': 'AUTHENTICATION_FAILED'}, 401 def delete(self): diff --git a/backend/app/urls.py b/backend/app/urls.py index e72d477..e34d1e9 100644 --- a/backend/app/urls.py +++ b/backend/app/urls.py @@ -1,3 +1,4 @@ +from app.api.UserInfoAPI import UserInfoAPI from app.api.exampleapi import SomeApi from app.api.loginAPI import LoginAPI from app.core import api diff --git a/backend/tests/api/test_loginAPI.py b/backend/tests/api/test_Auth.py similarity index 76% rename from backend/tests/api/test_loginAPI.py rename to backend/tests/api/test_Auth.py index d21eabb..b13869f 100644 --- a/backend/tests/api/test_loginAPI.py +++ b/backend/tests/api/test_Auth.py @@ -18,7 +18,8 @@ class AuthTestCase(unittest.TestCase): res = query.execute() cls.uid = res.lastrowid query = GROUP.insert().values(name="test", year="2017", class_long="classe toto", class_short="toto", - department="plop", ressources_dir="/plop/toto", resp_id=cls.uid) + department="plop", ressources_dir="/plop/toto", resp_id=cls.uid, + sec_id=cls.uid) res = query.execute() cls.gid = res.lastrowid query = TUTORSHIP.insert().values(student_id=cls.uid, ptutor_id=cls.uid, group_id=cls.gid) @@ -50,6 +51,9 @@ class AuthTestCase(unittest.TestCase): ) ), content_type='application/json') + def getUserInfo(self): + return self.app.get('/api/userInfo') + def logout(self): return self.app.delete('/api/login') @@ -57,12 +61,24 @@ class AuthTestCase(unittest.TestCase): rv = self.login('admin', 'admin') self.assertEqual(rv.status_code, 200, 'Login as admin Failed') + rv = self.login('admin', 'admin') + self.assertEqual(rv.status_code, 201, 'Login as admin succeed but should have already been done') + + rv = self.getUserInfo() + self.assertEqual(rv.status_code, 200, 'Getting user info failed') + self.assertEqual({"id": getUser(login="admin")["id"], "login": "admin", "email": "admin@admin.com", "role": 4, + "phone": "00.00.00.00.00"}, json.loads(rv.data)['USER'], 'Invalid user info') + rv = self.logout() self.assertEqual(rv.status_code, 200, 'Logout Failed') rv = self.login('adminx', 'admin') self.assertEqual(rv.status_code, 401, 'Authentication from CAS has not failed for the invalid user xadmin !') + rv = self.getUserInfo() + self.assertEqual(rv.status_code, 200, 'Getting user info failed') + self.assertIsNone(json.loads(rv.data)['USER'], 'User info should be None') + rv = self.login('admin', 'adminx') self.assertEqual(rv.status_code, 401, 'Authentication from CAS has not failed for the invalid password xadmin !') diff --git a/frontend/Gruntfile.js b/frontend/Gruntfile.js index dc80b6f..b8244a2 100644 --- a/frontend/Gruntfile.js +++ b/frontend/Gruntfile.js @@ -1,4 +1,4 @@ -// Generated on 2017-01-20 using generator-angular 0.15.1 +// Generated on 2017-02-26 using generator-angular 0.15.1 'use strict'; // # Globbing @@ -338,7 +338,7 @@ module.exports = function (grunt) { ngtemplates: { dist: { options: { - module: 'clientApp', + module: 'frontendApp', htmlmin: '<%= htmlmin.dist.options %>', usemin: 'scripts/scripts.js' }, diff --git a/frontend/app/images/yeoman.png b/frontend/app/images/yeoman.png deleted file mode 100644 index 92497ad..0000000 Binary files a/frontend/app/images/yeoman.png and /dev/null differ diff --git a/frontend/app/index.html b/frontend/app/index.html index 0be6125..7bbe0f3 100644 --- a/frontend/app/index.html +++ b/frontend/app/index.html @@ -8,7 +8,7 @@ - + @@ -20,6 +20,7 @@

You are using an outdated browser. Please upgrade your browser to improve your experience.

+ @@ -35,20 +36,20 @@ - - + + + + + - - - - + diff --git a/frontend/app/styles/main.css b/frontend/app/styles/main.css index b2e953f..9b89838 100644 --- a/frontend/app/styles/main.css +++ b/frontend/app/styles/main.css @@ -7,77 +7,5 @@ body { padding: 0; -} - -/* Everything but the jumbotron gets side spacing for mobile first views */ -.header, -.marketing, -.footer { - padding-left: 15px; - padding-right: 15px; -} - -/* Custom page header */ -.header { - border-bottom: 1px solid #e5e5e5; - margin-bottom: 10px; -} -/* Make the masthead heading the same height as the navigation */ -.header h3 { - margin-top: 0; - margin-bottom: 0; - line-height: 40px; - padding-bottom: 19px; -} - -/* Custom page footer */ -.footer { - padding-top: 19px; - color: #777; - border-top: 1px solid #e5e5e5; -} - -.container-narrow > hr { - margin: 30px 0; -} - -/* Main marketing message and sign up button */ -.jumbotron { - text-align: center; - border-bottom: 1px solid #e5e5e5; -} -.jumbotron .btn { - font-size: 21px; - padding: 14px 24px; -} - -/* Supporting marketing content */ -.marketing { - margin: 40px 0; -} -.marketing p + h4 { - margin-top: 28px; -} - -/* Responsive: Portrait tablets and up */ -@media screen and (min-width: 768px) { - .container { - max-width: 730px; - } - - /* Remove the padding we set earlier */ - .header, - .marketing, - .footer { - padding-left: 0; - padding-right: 0; - } - /* Space out the masthead */ - .header { - margin-bottom: 30px; - } - /* Remove the bottom border on the jumbotron for visual effect */ - .jumbotron { - border-bottom: 0; - } -} + background-color: #DADADA; +} \ No newline at end of file diff --git a/frontend/app/views/accueil.html b/frontend/app/views/accueil.html deleted file mode 100644 index 790318d..0000000 --- a/frontend/app/views/accueil.html +++ /dev/null @@ -1,62 +0,0 @@ - -
- -
- -
-
-

'Allo, 'Allo!

-

- I'm Yeoman
- Always a pleasure scaffolding your apps. -

-

Splendid!

-
- -
-

HTML5 Boilerplate

-

- HTML5 Boilerplate is a professional front-end template for building fast, robust, and adaptable web apps or sites. -

- -

Angular

-

- AngularJS is a toolset for building the framework most suited to your application development. -

- -

Karma

-

Spectacular Test Runner for JavaScript.

-
-
- - - - - diff --git a/frontend/app/views/login.html b/frontend/app/views/login.html new file mode 100644 index 0000000..0ded0cb --- /dev/null +++ b/frontend/app/views/login.html @@ -0,0 +1,25 @@ +
+
+ + + + Livret de l'alternant + + + + +
+ + + + + + + + +
+ Se connecter +
+
+
+
\ No newline at end of file diff --git a/frontend/bower.json b/frontend/bower.json index 96fdcd0..e95aa6c 100644 --- a/frontend/bower.json +++ b/frontend/bower.json @@ -1,24 +1,17 @@ { - "name": "client", + "name": "frontend", "version": "0.0.0", "dependencies": { - "angular": "^1.6.0", - "bootstrap": "^3.2.0", - "angular-sanitize": "^1.6.0", - "angular-ui-router": "1.0.0-beta.3" + "angular": "^1.4.0", + "angular-animate": "^1.4.0", + "angular-cookies": "^1.4.0", + "angular-sanitize": "^1.4.0", + "angular-material": "^1.1.3", + "angular-ui-router": "^0.4.2" }, "devDependencies": { - "angular-mocks": "^1.6.0" + "angular-mocks": "^1.4.0" }, "appPath": "app", - "moduleName": "clientApp", - "overrides": { - "bootstrap": { - "main": [ - "less/bootstrap.less", - "dist/css/bootstrap.css", - "dist/js/bootstrap.js" - ] - } - } + "moduleName": "clientApp" } diff --git a/frontend/package.json b/frontend/package.json index ba0c75b..8591e50 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -28,7 +28,7 @@ "jasmine-core": "^2.5.2", "jit-grunt": "^0.9.1", "jshint-stylish": "^1.0.0", - "karma": "^1.4.0", + "karma": "^1.5.0", "karma-jasmine": "^1.1.0", "karma-phantomjs-launcher": "^1.0.2", "phantomjs-prebuilt": "^2.1.14", @@ -39,6 +39,5 @@ }, "scripts": { "test": "karma start test/karma.conf.js" - }, - "dependencies": {} + } } diff --git a/frontend/test/karma.conf.js b/frontend/test/karma.conf.js index bca71cf..0ffd38c 100644 --- a/frontend/test/karma.conf.js +++ b/frontend/test/karma.conf.js @@ -1,5 +1,5 @@ // Karma configuration -// Generated on 2017-01-20 +// Generated on 2017-02-26 module.exports = function(config) { 'use strict'; @@ -20,10 +20,13 @@ module.exports = function(config) { // list of files / patterns to load in the browser files: [ // bower:js - 'bower_components/jquery/dist/jquery.js', 'bower_components/angular/angular.js', - 'bower_components/bootstrap/dist/js/bootstrap.js', + 'bower_components/angular-animate/angular-animate.js', + 'bower_components/angular-cookies/angular-cookies.js', 'bower_components/angular-sanitize/angular-sanitize.js', + 'bower_components/angular-aria/angular-aria.js', + 'bower_components/angular-messages/angular-messages.js', + 'bower_components/angular-material/angular-material.js', 'bower_components/angular-ui-router/release/angular-ui-router.js', 'bower_components/angular-mocks/angular-mocks.js', // endbower diff --git a/frontend/test/spec/controllers/main.js b/frontend/test/spec/controllers/main.js index 117e95b..cb2fd81 100644 --- a/frontend/test/spec/controllers/main.js +++ b/frontend/test/spec/controllers/main.js @@ -3,7 +3,7 @@ describe('Controller: MainCtrl', function () { // load the controller's module - beforeEach(module('clientApp')); + beforeEach(module('frontendApp')); var MainCtrl, scope; diff --git a/maquette/login.ep b/maquette/login.ep new file mode 100644 index 0000000..0bcb441 --- /dev/null +++ b/maquette/login.ep @@ -0,0 +1,155 @@ + +Login1485513931137_508611331384true#FFFFFFFF + + + + + + + + + + + + + + + + É um facto estabelecido de que um leitor é distraído pelo conteúdo +legível de uma página quando analisa a sua mancha gráfica. Logo, o uso +de Lorem Ipsum leva a uma distribuição mais ou menos normal de letras, +ao contrário do uso de "Conteúdo aqui, conteúdo aqui", tornando-o texto +legível. Muitas ferramentas de publicação electrónica e editores de +páginas web usam actualmente o Lorem Ipsum como o modelo de texto usado +por omissão, e uma pesquisa por "lorem ipsum" irá encontrar muitos
]]>
+ + + + + + + +
+ + + + + + + + + + + + Email + + + + + Mot de passe + + + + + Se connecter +
First Login Form1487875355622_843911331384true#FFFFFFFFtransparent + + + + + + + + + + + + + + + + + + + + Enregistrer + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/maquette/student_list.ep b/maquette/student_list.ep new file mode 100644 index 0000000..c9337c8 --- /dev/null +++ b/maquette/student_list.ep @@ -0,0 +1,575 @@ + +student period list1485514770935_65131534699true#FFFFFFFFtransparent + + + + + + + + + + + + + + + + + + + + Se déconnecter + + Bienvenue Thomas Vulope]]> + + +
Bienvenue Thomas Vulope
+
+
+ + + + + + + + + + + + + + + + ]]> + + +
Période 2
+
+
+ + + + + + + + + + + + + + + + + + + + Éditer + + + + + Éditer + + +
Entreprise
+
+
+ +
Formation
+
+
+ + + + + + + + ]]> + + +
Période 1
+
+
+ + + + + + + + + + + + + + + + + + + + Éditer + + +
Entreprise
+
+
+ +
Formation
+
+
+ + + + Éditer + + + + + Exporter le livret + +
student period details1485516232196_10301534699true#FFFFFFFFtransparent + + + + + + + + + + + + + + + + + + + + Se déconnecter + + Bienvenue Thomas Vulope]]> + + +
Bienvenue Thomas Vulope
+
+
+ + + + + + + + + + + + + + + + ]]> + + +
Période 2
+
+
+ + + + + + + + + +
Entreprise
+
+
+ + + + + + + + ]]> + + +
Période 1
+
+
+ +
+
+
+ + + + Exporter le livret + + + + + + + + + + +
Formation
+
+
+ + + + + + + + + + + Enregistrer + +
secretariat1487877876391_5481534699true#FFFFFFFFtransparent + + + + + + + + + + + + + + + + + + + + Se déconnecter + + Bienvenue Thomas Vulope]]> + + +
Bienvenue Thomas Vulope
+
+
+ + + + + + + + + + + + Importer les fichies d'absence + + + + + Ajouter une fiche de visite + + + + + + + + + + + + + + +
MenuItem
MenuItem
MenuItem
+
+ + + +
+ + + + + +
MenuItem
MenuItem
MenuItem
+
+ + + +
]]> + + +
Fiches d'absences
+
+
]]> + + +
Fiches de visite
+
+
tuteur entreprise1487879006916_71761534699true#FFFFFFFFtransparent + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + +
Période 2
+
+
+ + + + + + + + + +
Entreprise
+
+
+ + + + + + + + ]]> + + +
Période 1
+
+
+ +
+
+
+ + + + Exporter le livret + + + + + + + + + + +
Formation
+
+
+ + + + + + + + + + + Enregistrer + +
Rich text Rich textRich textRich textRich textRich textRich text]]>
+ + +
Description de la periode en entreprise :

Rich text Rich textRich textRich textRich textRich textRich text
+
+
\ No newline at end of file