From f6bb5bc614ce18ee0204b7ec322abfe180696844 Mon Sep 17 00:00:00 2001 From: Oliver Facklam <oliver.facklam.lfgeb@gmail.com> Date: Sun, 30 Dec 2018 14:21:13 +0100 Subject: [PATCH] =?UTF-8?q?Am=C3=A9lioration=20gestion=20des=20erreurs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/graphql/connectors/userModel.ts | 109 +++++++++++++--------------- src/graphql/resolvers/groups.ts | 83 +++++++++++---------- src/graphql/resolvers/messages.ts | 82 ++++++++++----------- src/graphql/resolvers/requests.ts | 52 +++++++------ src/graphql/resolvers/users.ts | 15 ++-- 5 files changed, 162 insertions(+), 179 deletions(-) diff --git a/src/graphql/connectors/userModel.ts b/src/graphql/connectors/userModel.ts index b819166..5906c6c 100644 --- a/src/graphql/connectors/userModel.ts +++ b/src/graphql/connectors/userModel.ts @@ -4,10 +4,10 @@ * @memberof GraphQL */ -import { AuthorisationModel } from "./authorisationModel"; import { User } from "../resolvers/users"; import { User as UT, userData } from "../../ldap/export/user" import { searchTOLArgs, editProfileArgs } from "../typeDefs/queries"; +import { ApolloError } from "apollo-server-core"; export class UserModel { @@ -16,13 +16,13 @@ export class UserModel { * @class UserModel * @summary Requetes relatives aux utilisateurs. * @classdesc Cette classe contient les méthodes implémentant les requetes relatives aux utilisateurs. - * @arg {AuthorisationModel} auth - Le module d'auth + * @arg {string} contextUser - L'identifiant de l'utilisateur du 'context' */ - constructor(auth: AuthorisationModel) { - this.auth = auth; + constructor(contextUser: string) { + this.contextUser = contextUser; } - protected auth: AuthorisationModel; + protected contextUser: string; /** * @memberof GraphQL.UserModel# @@ -34,10 +34,7 @@ export class UserModel { * @rights connectedOrOnplatal */ async getUser(uid: string): Promise<User> { - if(this.auth.isConnectedOrOnplatal()) { - return User.tryCreate(uid); - } - return null; + return User.tryCreate(uid); } /** @@ -50,24 +47,21 @@ export class UserModel { * @rights connectedOrOnplatal */ async searchTOL(args: searchTOLArgs): Promise<User[]> { - if(this.auth.isConnectedOrOnplatal()) { - const searchData: userData = { - givenName: args.givenName, - lastName: args.lastName, - nickname: args.nickname, - nationality: args.nationality, - promotion: args.promotion, - groups: args.groups, - sport: args.sport, - phone: args.phone, - mail: args.mail, - address: args.addresses[0], - ips: args.ips - } - const userList = await UT.search(searchData); - return userList.map((uid) => new User(uid)); + const searchData: userData = { + givenName: args.givenName, + lastName: args.lastName, + nickname: args.nickname, + nationality: args.nationality, + promotion: args.promotion, + groups: args.groups, + sport: args.sport, + phone: args.phone, + mail: args.mail, + address: args.addresses[0], + ips: args.ips } - return null; + const userList = await UT.search(searchData); + return userList.map((uid) => new User(uid)); } /** @@ -80,42 +74,39 @@ export class UserModel { * @rights authentified */ async editProfile(args: editProfileArgs): Promise<User> { - if (this.auth.isAuthenticated()) { - let data = await UT.peek(this.auth.getUid()); + let data = await UT.peek(this.contextUser); - //Modify some fields, keep the others - let editArgs: userData = { - uid: data.uid, - groups: data.groups, - groupsIsAdmin: data.groupsIsAdmin, - password: data.password, - givenName: data.givenName, - lastName: data.lastName, - nickname: args.nickname, // <- this field is modified by user - promotion: data.promotion, - photo: data.photo, - birthdate: data.birthdate, - nationality: data.nationality, - phone: args.phone, // <- this field is modified - address: data.address, // WTF why can't this be changed ???? - mail: args.mail, // <- this field is modified - ips: data.ips, - directory: data.directory, - login: data.login, - readPerm: data.readPerm, - writePerm: data.writePerm, - forlifes: data.forlifes, - sport: data.sport - }; + //Modify some fields, keep the others + let editArgs: userData = { + uid: data.uid, + groups: data.groups, + groupsIsAdmin: data.groupsIsAdmin, + password: data.password, + givenName: data.givenName, + lastName: data.lastName, + nickname: args.nickname, // <- this field is modified by user + promotion: data.promotion, + photo: data.photo, + birthdate: data.birthdate, + nationality: data.nationality, + phone: args.phone, // <- this field is modified + address: data.address, // WTF why can't this be changed ???? + mail: args.mail, // <- this field is modified + ips: data.ips, + directory: data.directory, + login: data.login, + readPerm: data.readPerm, + writePerm: data.writePerm, + forlifes: data.forlifes, + sport: data.sport + }; - if(await UT.edit(editArgs)) { - return new User(data.uid); - } - else { - throw "Modification échouée"; - } + if(await UT.edit(editArgs)) { + return new User(data.uid); + } + else { + throw new ApolloError("Edit failed"); } - return null; } } \ No newline at end of file diff --git a/src/graphql/resolvers/groups.ts b/src/graphql/resolvers/groups.ts index 5f5dc40..f500264 100644 --- a/src/graphql/resolvers/groups.ts +++ b/src/graphql/resolvers/groups.ts @@ -8,6 +8,7 @@ import {Announcement, Event, PrivatePost, Question, Answer} from './messages'; import {Group as LDAP_Group} from '../../ldap/export/group'; import knex from '../../../db/knex_router'; import { Context } from '../typeDefs/queries'; +import { ApolloError, AuthenticationError } from 'apollo-server-core'; export abstract class Group { @@ -30,12 +31,12 @@ export abstract class Group { * @memberof GraphQL.Group# * @function fetchData * @summary Fonction qui va chercher toutes les données sur ce groupe dans le stockage approprié, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected * @abstract */ - protected abstract async fetchData(): Promise<void> + protected abstract async fetchData(): Promise<boolean> /** * Protected properties. @@ -73,7 +74,7 @@ export abstract class Group { return "MetaGroup" } else { - throw "Mauvais type de groupe"; + throw new ApolloError("Bad group type"); } } @@ -132,7 +133,7 @@ export abstract class Group { await this.fetchData(); return this.m_description; } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -148,7 +149,7 @@ export abstract class Group { await this.fetchData(); return this.m_mail; } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -164,7 +165,7 @@ export abstract class Group { await this.fetchData(); return this.m_website; } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -191,7 +192,7 @@ export abstract class Group { await this.fetchData(); return this.m_frontPage; } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -206,7 +207,7 @@ export abstract class Group { if (context.models.auth.isViewer(this.gid)) { throw "Not implemented" } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -221,7 +222,7 @@ export abstract class Group { if (context.models.auth.isViewer(this.gid)) { throw "Not implemented" } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -236,7 +237,7 @@ export abstract class Group { if(context.models.auth.isMember(this.gid)) { throw "Not implemented" } - throw "Not a member" + throw new AuthenticationError("Not a member"); } /** @@ -251,7 +252,7 @@ export abstract class Group { if (context.models.auth.isMember(this.gid)) { throw "Not implemented" } - throw "Not a member" + throw new AuthenticationError("Not a member"); } /** @@ -266,7 +267,7 @@ export abstract class Group { if (context.models.auth.isMember(this.gid)) { throw "Not implemented" } - throw "Not a member" + throw new AuthenticationError("Not a member"); } /** @@ -281,7 +282,7 @@ export abstract class Group { if (context.models.auth.isMember(this.gid)) { throw "Not implemented" } - throw "Not a member" + throw new AuthenticationError("Not a member"); } /** @@ -296,7 +297,7 @@ export abstract class Group { if (context.models.auth.isMember(this.gid)) { throw "Not implemented" } - throw "Not a member" + throw new AuthenticationError("Not a member"); } /** @@ -312,7 +313,7 @@ export abstract class Group { await this.fetchData(); return this.m_postsSummary; } - throw "Not a member" + throw new AuthenticationError("Not a member"); } /** @@ -327,7 +328,7 @@ export abstract class Group { if (context.models.auth.isViewer(this.gid)) { throw "Not implemented" } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } } @@ -360,24 +361,21 @@ export class SimpleGroup extends Group { */ static async tryCreate(gid: string): Promise<SimpleGroup> { let g = new SimpleGroup(gid); - try { - await g.fetchData(); + if(await g.fetchData()) { return g; } - catch { - return null; - } + return null; } /** * @memberof GraphQL.SimpleGroup# * @function fetchData * @summary Fonction qui va chercher toutes les données sur ce groupe simple dans le LDAP, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected */ - protected async fetchData(): Promise<void> { + protected async fetchData(): Promise<boolean> { if(!this.m_dataLoaded) { try { let data = await LDAP_Group.peek(this.gid); @@ -405,11 +403,13 @@ export class SimpleGroup extends Group { //this.m_school = ???; this.m_dataLoaded = true; + return true; } catch { - throw "Not_found"; + return false; } } + return true; } /** @@ -446,7 +446,7 @@ export class SimpleGroup extends Group { return new User(uid); }); } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -464,7 +464,7 @@ export class SimpleGroup extends Group { return new User(uid); }); } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -482,7 +482,7 @@ export class SimpleGroup extends Group { return new User(uid); }); } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -500,7 +500,7 @@ export class SimpleGroup extends Group { return new User(uid); }); } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -521,7 +521,7 @@ export class SimpleGroup extends Group { return new SimpleGroup(this.m_parent); } } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -539,7 +539,7 @@ export class SimpleGroup extends Group { return new SimpleGroup(gid); }); } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -554,7 +554,7 @@ export class SimpleGroup extends Group { if(context.models.auth.isViewer(this.gid)) { throw "Not implemented"; } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -570,7 +570,7 @@ export class SimpleGroup extends Group { await this.fetchData(); return this.m_school; } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } } @@ -603,24 +603,21 @@ export class MetaGroup extends Group { */ static async tryCreate(gid: string): Promise<MetaGroup> { let g = new MetaGroup(gid); - try { - await g.fetchData(); + if(await g.fetchData()) { return g; } - catch { - return null; - } + return null; } /** * @memberof GraphQL.MetaGroup# * @function fetchData * @summary Fonction qui va chercher toutes les données sur ce méta-groupe dans la BDD, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected */ - protected async fetchData(): Promise<void> { + protected async fetchData(): Promise<boolean> { if (!this.m_dataLoaded) { let data = await knex.select('created_at', 'updated_at', @@ -645,11 +642,13 @@ export class MetaGroup extends Group { //this.m_postsSummary = g.postsSummary; this.m_dataLoaded = true; + return true; } else { - throw "Not_found"; + return false; } } + return true; } /** @@ -668,7 +667,7 @@ export class MetaGroup extends Group { if (context.models.auth.isViewer(this.gid)) { throw "Not implemented"; } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } /** @@ -683,7 +682,7 @@ export class MetaGroup extends Group { if (context.models.auth.isViewer(this.gid)) { throw "Not implemented" } - throw "Not a viewer"; + throw new AuthenticationError("Not a viewer"); } } \ No newline at end of file diff --git a/src/graphql/resolvers/messages.ts b/src/graphql/resolvers/messages.ts index cde94b5..fcbe3c0 100644 --- a/src/graphql/resolvers/messages.ts +++ b/src/graphql/resolvers/messages.ts @@ -7,6 +7,7 @@ import {Group, SimpleGroup, MetaGroup} from './groups'; import {User} from './users'; import knex from '../../../db/knex_router'; import { Context } from '../typeDefs/queries'; +import { ApolloError } from 'apollo-server-core'; export abstract class Message { @@ -29,12 +30,12 @@ export abstract class Message { * @memberof GraphQL.Message# * @function fetchData * @summary Fonction qui va chercher toutes les données sur ce message dans la BDD, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected * @abstract */ - protected abstract async fetchData(): Promise<void> + protected abstract async fetchData(): Promise<boolean> /** * Protected properties. @@ -78,7 +79,7 @@ export abstract class Message { return "PrivatePost"; } else { - throw "Mauvais type de message"; + throw new ApolloError("Bad message type"); } } @@ -166,24 +167,21 @@ export class Announcement extends Message { */ static async tryCreate(mid: number): Promise<Announcement> { let m = new Announcement(mid); - try { - await m.fetchData(); + if(await m.fetchData()) { return m; } - catch { - return null; - } + return null; } /** * @memberof GraphQL.Announcement# * @function fetchData * @summary Fonction qui va chercher toutes les données sur cet announcement dans la BDD, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected */ - protected async fetchData(): Promise<void> { + protected async fetchData(): Promise<boolean> { if(!this.m_dataLoaded) { let data = await knex.select('created_at', 'updated_at', @@ -203,11 +201,13 @@ export class Announcement extends Message { this.m_views = m.views; this.m_dataLoaded = true; + return true; } else { - throw "Not_found"; + return false; } } + return true; } /** @@ -319,24 +319,21 @@ export class Event extends Message { */ static async tryCreate(mid: number): Promise<Event> { let m = new Event(mid); - try { - await m.fetchData(); + if(await m.fetchData()) { return m; } - catch { - return null; - } + return null; } /** * @memberof GraphQL.Event# * @function fetchData * @summary Fonction qui va chercher toutes les données sur cet event dans la BDD, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected */ - protected async fetchData(): Promise<void> { + protected async fetchData(): Promise<boolean> { if (!this.m_dataLoaded) { let data = await knex.select('created_at', 'updated_at', @@ -360,11 +357,13 @@ export class Event extends Message { this.m_forAnnouncement = m.for_announcement; this.m_dataLoaded = true; + return true; } else { - throw "Not_found"; + return false; } } + return true; } /** @@ -517,24 +516,21 @@ export class PrivatePost extends Message { */ static async tryCreate(mid: number): Promise<PrivatePost> { let m = new PrivatePost(mid); - try { - await m.fetchData(); + if(await m.fetchData()) { return m; } - catch { - return null; - } + return null; } /** * @memberof GraphQL.PrivatePost# * @function fetchData * @summary Fonction qui va chercher toutes les données sur ce post privé dans la BDD, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected */ - protected async fetchData(): Promise<void> { + protected async fetchData(): Promise<boolean> { if (!this.m_dataLoaded) { let data = await knex.select('created_at', 'updated_at', @@ -554,11 +550,13 @@ export class PrivatePost extends Message { this.m_recipient = m.recipient; this.m_dataLoaded = true; + return true; } else { - throw "Not_found"; + return false; } } + return true; } /** @@ -630,24 +628,21 @@ export class Question extends Message { */ static async tryCreate(mid: number): Promise<Question> { let m = new Question(mid); - try { - await m.fetchData(); + if(await m.fetchData()) { return m; } - catch { - return null; - } + return null; } /** * @memberof GraphQL.Question# * @function fetchData * @summary Fonction qui va chercher toutes les données sur ce post privé dans la BDD, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected */ - protected async fetchData(): Promise<void> { + protected async fetchData(): Promise<boolean> { if (!this.m_dataLoaded) { let data = await knex.select('created_at', 'updated_at', @@ -667,11 +662,13 @@ export class Question extends Message { this.m_recipient = m.recipient; this.m_dataLoaded = true; + return true; } else { - throw "Not_found"; + return false; } } + return true; } /** @@ -759,24 +756,21 @@ export class Answer extends Message { */ static async tryCreate(mid: number): Promise<Answer> { let m = new Answer(mid); - try { - await m.fetchData(); + if(await m.fetchData()) { return m; } - catch { - return null; - } + return null; } /** * @memberof GraphQL.Answer# * @function fetchData * @summary Fonction qui va chercher toutes les données sur ce post privé dans la BDD, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected */ - protected async fetchData(): Promise<void> { + protected async fetchData(): Promise<boolean> { if (!this.m_dataLoaded) { let data = await knex.select('created_at', 'updated_at', @@ -796,11 +790,13 @@ export class Answer extends Message { this.m_forQuestion = m.for_question; this.m_dataLoaded = true; + return true; } else { - throw "Not_found"; + return false; } } + return true; } /** diff --git a/src/graphql/resolvers/requests.ts b/src/graphql/resolvers/requests.ts index 3f5cc05..7c1a2c5 100644 --- a/src/graphql/resolvers/requests.ts +++ b/src/graphql/resolvers/requests.ts @@ -8,6 +8,7 @@ import { User } from './users'; import { Event } from "./messages"; import knex from '../../../db/knex_router'; import { Context } from "../typeDefs/queries"; +import { ApolloError } from "apollo-server-core"; export abstract class Request { @@ -30,12 +31,12 @@ export abstract class Request { * @memberof GraphQL.Request# * @function fetchData * @summary Fonction qui va chercher toutes les données sur cette requete dans la BDD, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected * @abstract */ - protected abstract async fetchData(): Promise<void> + protected abstract async fetchData(): Promise<boolean> /** * Protected properties. @@ -72,7 +73,7 @@ export abstract class Request { return "GroupCoauthorEvent"; } else { - throw "Mauvais type de requete"; + throw new ApolloError("Bad request type"); } } @@ -143,24 +144,21 @@ export class UserJoinGroup extends Request { */ static async tryCreate(rid: number): Promise<UserJoinGroup> { let r = new UserJoinGroup(rid); - try { - await r.fetchData(); + if(await r.fetchData()) { return r; } - catch { - return null; - } + return null; } /** * @memberof GraphQL.UserJoinGroup# * @function fetchData * @summary Fonction qui va chercher toutes les données sur cette requete dans la BDD, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected */ - protected async fetchData(): Promise<void> { + protected async fetchData(): Promise<boolean> { if (!this.m_dataLoaded) { let data = await knex.select('request_comment', 'request_from', @@ -174,11 +172,13 @@ export class UserJoinGroup extends Request { this.m_to = r.request_to; this.m_dataLoaded = true; + return true; } else { - throw "Not_found"; + return false; } } + return true; } /** @@ -240,24 +240,21 @@ export class GroupJoinMetagroup extends Request { */ static async tryCreate(rid: number): Promise<GroupJoinMetagroup> { let r = new GroupJoinMetagroup(rid); - try { - await r.fetchData(); + if(await r.fetchData()) { return r; } - catch { - return null; - } + return null; } /** * @memberof GraphQL.GroupJoinMetagroup# * @function fetchData * @summary Fonction qui va chercher toutes les données sur cette requete dans la BDD, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected */ - protected async fetchData(): Promise<void> { + protected async fetchData(): Promise<boolean> { if (!this.m_dataLoaded) { let data = await knex.select('request_comment', 'request_from', @@ -271,11 +268,13 @@ export class GroupJoinMetagroup extends Request { this.m_to = r.request_to; this.m_dataLoaded = true; + return true; } else { - throw "Not_found"; + return false; } } + return true; } /** @@ -337,24 +336,21 @@ export class GroupCoauthorEvent extends Request { */ static async tryCreate(rid: number): Promise<GroupCoauthorEvent> { let r = new GroupCoauthorEvent(rid); - try { - await r.fetchData(); + if(await r.fetchData()) { return r; } - catch { - return null; - } + return null; } /** * @memberof GraphQL.GroupCoauthorEvent# * @function fetchData * @summary Fonction qui va chercher toutes les données sur cette requete dans la BDD, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected */ - protected async fetchData(): Promise<void> { + protected async fetchData(): Promise<boolean> { if (!this.m_dataLoaded) { let data = await knex.select('request_comment', 'request_from', @@ -370,11 +366,13 @@ export class GroupCoauthorEvent extends Request { this.m_forEvent = r.for_event; this.m_dataLoaded = true; + return true; } else { - throw "Not_found"; + return false; } } + return true; } /** diff --git a/src/graphql/resolvers/users.ts b/src/graphql/resolvers/users.ts index 1401800..ff5bc8a 100644 --- a/src/graphql/resolvers/users.ts +++ b/src/graphql/resolvers/users.ts @@ -37,24 +37,21 @@ export class User { */ static async tryCreate(uid: string): Promise<User> { let u = new User(uid); - try { - await u.fetchData(); + if(await u.fetchData()) { return u; } - catch { - return null; - } + return null; } /** * @memberof GraphQL.User# * @function fetchData * @summary Fonction qui va chercher toutes les données sur ce user dans le LDAP, si ce n'est pas déja fait. - * @throws {Not_found} Les données n'ont pas pu etre trouvées. + * @returns {Promise(boolean)} Renvoie true si le chargement est réussi. * @async * @protected */ - protected async fetchData(): Promise<void> { + protected async fetchData(): Promise<boolean> { if(!this.m_dataLoaded) { try { let data = await LDAP_User.peek(this.uid); @@ -79,11 +76,13 @@ export class User { //this.m_likes = data.likes; this.m_dataLoaded = true; + return true; } catch { - throw "Not_found"; + return false; } } + return true; } /** -- GitLab