Commit 598c3d42 authored by Boiget Boiget's avatar Boiget Boiget

Add server-side logging function with notification option

parent 9d9253bc
Pipeline #2331 failed with stages
in 2 minutes and 12 seconds
......@@ -194,6 +194,12 @@
"addGroupFolderError": "Error, could not create group folder in Nextcloud",
"removeGroupError": "Warning, could not delete group in Nextcloud",
"removeGroupFolderError": "Warning, could not delete group folder in Nextcloud"
},
"logging": {
"unknownLogLevel": "Specified log level does not exist",
"info": "Server information",
"warning": "Server warning",
"error": "Server error"
}
},
"components": {
......
......@@ -194,6 +194,12 @@
"addGroupFolderError": "Erreur lors de la création du partage dans Nextcloud",
"removeGroupError": "Attention, le groupe n'a pas pu être supprimé dans Nextcloud",
"removeGroupFolderError": "Attention, le dossier n'a pas pu être supprimé dans Nextcloud"
},
"logging": {
"unknownLogLevel": "Le niveau de log spécifié n'existe pas",
"info": "Information serveur",
"warning": "Avertissement serveur",
"error": "Erreur serveur"
}
},
"components": {
......
This diff is collapsed.
import axios from 'axios';
import { Meteor } from 'meteor/meteor';
import logServer from '../logging';
const _checkFolderActive = function (response) {
function checkFolderActive(response) {
// checks that 'Group Folder' API is responding
if (response.data === undefined || response.data.ocs === undefined) {
console.log(`Nexcloud: ERROR, make sure 'Group Folders' application is active`);
logServer(`Nexcloud: ERROR, make sure 'Group Folders' application is active`, 'error');
return false;
}
return true;
};
}
class NextcloudClient {
constructor() {
......@@ -36,8 +37,8 @@ class NextcloudClient {
return response.data.ocs.data.groups.includes(groupName);
})
.catch((error) => {
console.log(`Nextcloud: ERROR getting group ${groupName}`);
console.log(error.response && error.response.data ? error.response.data : error);
logServer(`Nextcloud: ERROR getting group ${groupName}`, 'error');
logServer(error.response && error.response.data ? error.response.data : error, 'error');
return false;
});
}
......@@ -60,15 +61,15 @@ class NextcloudClient {
.then((response) => {
const infos = response.data.ocs.meta;
if (infos.status === 'ok') {
console.log(`Nextcloud: group ${groupName} added`);
logServer(`Nextcloud: group ${groupName} added`);
} else {
console.log(`Nextcloud: ERROR adding group ${groupName} (${infos.statuscode} - ${infos.message})`);
logServer(`Nextcloud: ERROR adding group ${groupName} (${infos.statuscode} - ${infos.message})`, 'error');
}
return infos.status === 'ok' ? infos.status : infos.message;
})
.catch((error) => {
console.log(`Nextcloud: ERROR adding group ${groupName}`);
console.log(error.response && error.response.data ? error.response.data : error);
logServer(`Nextcloud: ERROR adding group ${groupName}`, 'error');
logServer(error.response && error.response.data ? error.response.data : error, 'error');
return `Nextcloud: ERROR adding group ${groupName}`;
});
}
......@@ -109,7 +110,7 @@ class NextcloudClient {
)
.then((resp) => resp.data.ocs.meta.status === 'ok');
}
console.log(`Nextcloud: could not assign group ${groupName} to folder ${folderName}`);
logServer(`Nextcloud: could not assign group ${groupName} to folder ${folderName}`, 'error');
return false;
});
}
......@@ -134,7 +135,7 @@ class NextcloudClient {
)
.then((response) => {
const infos = response.data.ocs.meta;
if (_checkFolderActive(response) && infos.status === 'ok') {
if (checkFolderActive(response) && infos.status === 'ok') {
return true;
}
return false;
......@@ -160,30 +161,30 @@ class NextcloudClient {
)
.then((response) => {
const infos = response.data.ocs.meta;
if (_checkFolderActive(response) && infos.status === 'ok') {
console.log(`Nextcloud: group folder ${folderName} added`);
if (checkFolderActive(response) && infos.status === 'ok') {
logServer(`Nextcloud: group folder ${folderName} added`);
return this._addGroupToFolder(groupName, folderName, response.data.ocs.data.id).then((resp) => {
if (resp === true) {
console.log(`Nextcloud: access and permissions set for group folder ${folderName}`);
logServer(`Nextcloud: access and permissions set for group folder ${folderName}`);
return this._addQuotaToFolder(response.data.ocs.data.id).then((respQuota) => {
if (respQuota) {
console.log(`Nextcloud: quota set for group folder ${folderName}`);
logServer(`Nextcloud: quota set for group folder ${folderName}`);
} else {
console.log(`Nextcloud: ERROR setting quota on group folder ${folderName}`);
logServer(`Nextcloud: ERROR setting quota on group folder ${folderName}`, 'error');
}
return respQuota;
});
}
console.log(`Nextcloud: ERROR settings group permissions for group folder ${folderName}`);
logServer(`Nextcloud: ERROR settings group permissions for group folder ${folderName}`, 'error');
return resp;
});
}
console.log(`Nextcloud: ERROR adding group folder ${folderName}`);
logServer(`Nextcloud: ERROR adding group folder ${folderName}`, 'error');
return false;
})
.catch((error) => {
console.log(`Nextcloud: ERROR adding group folder ${folderName}`);
console.log(error.response && error.response.data ? error.response.data : error);
logServer(`Nextcloud: ERROR adding group folder ${folderName}`, 'error');
logServer(error.response && error.response.data ? error.response.data : error, 'error');
return false;
});
}
......@@ -199,7 +200,7 @@ class NextcloudClient {
},
})
.then((response) => {
if (_checkFolderActive(response) && response.data.ocs.meta.status === 'ok') {
if (checkFolderActive(response) && response.data.ocs.meta.status === 'ok') {
// find groupFolder ID for groupName
const folders = Object.values(response.data.ocs.data).filter((entry) => {
return entry.mount_point === groupName && Object.keys(entry.groups).includes(groupName);
......@@ -219,10 +220,10 @@ class NextcloudClient {
.then((resp) => {
const infos = resp.data.ocs.meta;
if (infos.status === 'ok') {
console.log(`Nextcloud: removed group folder ${folder.id} (${folder.mount_point})`);
logServer(`Nextcloud: removed group folder ${folder.id} (${folder.mount_point})`);
return true;
}
console.log(`Nextcloud: ERROR deleting group folder ${folder.id} (${infos.message})`);
logServer(`Nextcloud: ERROR deleting group folder ${folder.id} (${infos.message})`, 'error');
return false;
});
}),
......@@ -243,15 +244,15 @@ class NextcloudClient {
.then((response) => {
const infos = response.data.ocs.meta;
if (infos.status === 'ok') {
console.log(`Nextcloud: group ${groupName} removed`);
logServer(`Nextcloud: group ${groupName} removed`);
} else {
console.log(`Nextcloud: Error removing group ${groupName} (${infos.message})`);
logServer(`Nextcloud: Error removing group ${groupName} (${infos.message})`, 'error');
}
return infos.status === 'ok';
})
.catch((error) => {
console.log(`Nextcloud: ERROR removing group ${groupName}`);
console.log(error.response && error.response.data ? error.response.data : error);
logServer(`Nextcloud: ERROR removing group ${groupName}`, 'error');
logServer(error.response && error.response.data ? error.response.data : error, 'error');
return false;
});
}
......
......@@ -9,6 +9,7 @@ import Minio from 'minio';
import s3Client from './config';
import { isActive } from '../../utils';
import logServer from '../../logging';
const { minioSSL, minioEndPoint, minioBucket, minioPort } = Meteor.settings.public;
......@@ -160,10 +161,11 @@ export const moveFiles = new ValidatedMethod({
(err) => {
s3Client.removeObject(minioBucket, `${sourcePath}/${newFile}`);
if (err) {
console.log(
logServer(
`Error copying ${newFile} from ${minioBucket}/${sourcePath}/${newFile} to ${destinationPath}/${newFile}`,
'error',
);
console.log(err);
logServer(err, 'error');
}
},
);
......
......@@ -130,7 +130,7 @@ Groups.schema = new SimpleSchema(
{ tracker: Tracker },
);
Groups.after.update(function (_, doc, fieldNames) {
Groups.after.update(function countCandidates(_, doc, fieldNames) {
if (fieldNames.includes('candidates')) {
if (!this.previous.candidates || this.previous.candidates.length !== doc.candidates.length) {
Groups.update({ _id: doc._id }, { $set: { numCandidates: doc.candidates.length } });
......
......@@ -104,7 +104,7 @@ export const createGroup = new ValidatedMethod({
}
if (kcClient) {
// create associated groups and roles in keycloak
kcClient.addGroup({ name });
kcClient.addGroup({ name }, this.userId);
}
if (nextcloud && nextClient) {
// create associated group in Nextcloud
......@@ -149,7 +149,7 @@ export const removeGroup = new ValidatedMethod({
}
if (kcClient) {
// delete associated groups and roles in keycloak
kcClient.removeGroup(group);
kcClient.removeGroup(group, this.userId);
}
// remove all roles set on this group
Roles.removeScope(groupId);
......@@ -241,7 +241,7 @@ export const updateGroup = new ValidatedMethod({
}
// update group in keycloak if name has changed
if (kcClient && groupData.name && groupData.name !== group.name) {
kcClient.updateGroup(group.name, groupData.name);
kcClient.updateGroup(group.name, groupData.name, this.userId);
}
// create nextcloud group if needed
const nextRequired = data.nextcloud === true || (data.nextcloud === undefined && group.nextcloud === true);
......
......@@ -9,6 +9,7 @@ import { isActive } from '../utils';
import PersonalSpaces from './personalspaces';
import Groups from '../groups/groups';
import Services from '../services/services';
import logServer from '../logging';
const addItem = (userId, item) => {
const currentPersonalSpace = PersonalSpaces.findOne({ userId });
......@@ -133,7 +134,7 @@ export const checkPersonalSpace = new ValidatedMethod({
const currentPersonalSpace = PersonalSpaces.findOne({ userId: this.userId });
if (currentPersonalSpace === undefined) {
const u = Meteor.users.findOne({ _id: this.userId }, { fields: { username: 1, favServices: 1, favGroups: 1 } });
console.log(`Regen personalspaces for ${u.username}...`);
logServer(`Regen personalspaces for ${u.username}...`);
const unsorted = [];
u.favServices.forEach((s) => {
unsorted.push({
......@@ -159,7 +160,7 @@ export const checkPersonalSpace = new ValidatedMethod({
const elem = zone[index];
if (elementIds.indexOf(elem.element_id) !== -1) {
// We have a duplicate card to delete
console.log(
logServer(
`Remove personalspace duplicate ${elem.type} for ${
Meteor.users.findOne({ _id: this.userId }, { fields: { username: 1 } }).username
}...`,
......@@ -174,7 +175,7 @@ export const checkPersonalSpace = new ValidatedMethod({
const group = Groups.findOne(elem.element_id);
if (group === undefined) {
// group no more exists so delete element
console.log(
logServer(
`Remove personalspace no more existing group for ${
Meteor.users.findOne({ _id: this.userId }, { fields: { username: 1 } }).username
}...`,
......
......@@ -293,7 +293,7 @@ export const setAdmin = new ValidatedMethod({
}
if (Meteor.settings.public.enableKeycloak) {
// update user's groups in Keycloak
kcClient.setAdmin(userId);
kcClient.setAdmin(userId, this.userId);
}
// add role to user collection
Roles.addUsersToRoles(userId, 'admin');
......@@ -366,7 +366,7 @@ export const unsetAdmin = new ValidatedMethod({
}
if (Meteor.settings.public.enableKeycloak) {
// update user's groups in Keycloak
kcClient.unsetAdmin(userId);
kcClient.unsetAdmin(userId, this.userId);
}
// remove role from user collection
Roles.removeUsersFromRoles(userId, 'admin');
......@@ -484,7 +484,7 @@ export const setAnimatorOf = new ValidatedMethod({
favGroup._execute({ userId }, { groupId });
if (kcClient && !Roles.userIsInRole(userId, 'member', groupId)) {
// update user's groups in Keycloak
kcClient.setRole(userId, group.name);
kcClient.setRole(userId, group.name, this.userId);
// kcClient.setRole(userId, `animator_${group.name}`);
}
// Notify user
......@@ -525,7 +525,7 @@ export const unsetAnimatorOf = new ValidatedMethod({
}
if (kcClient && !Roles.userIsInRole(userId, 'member', groupId)) {
// update user's groups in Keycloak
kcClient.unsetRole(userId, group.name);
kcClient.unsetRole(userId, group.name, this.userId);
// kcClient.unsetRole(userId, `animator_${group.name}`);
}
// Notify user
......@@ -578,7 +578,7 @@ export const setMemberOf = new ValidatedMethod({
favGroup._execute({ userId }, { groupId });
if (kcClient && !Roles.userIsInRole(userId, 'animator', groupId)) {
// update user's groups in Keycloak
kcClient.setRole(userId, group.name);
kcClient.setRole(userId, group.name, this.userId);
// kcClient.setRole(userId, `member_${group.name}`);
}
// Notify user
......@@ -621,7 +621,7 @@ export const unsetMemberOf = new ValidatedMethod({
}
if (kcClient && !Roles.userIsInRole(userId, 'animator', groupId)) {
// update user's groups in Keycloak
kcClient.unsetRole(userId, group.name);
kcClient.unsetRole(userId, group.name, this.userId);
// kcClient.unsetRole(userId, `member_${group.name}`);
}
// Notify user
......
......@@ -3,7 +3,9 @@ import SimpleSchema from 'simpl-schema';
import { Tracker } from 'meteor/tracker';
import { Roles } from 'meteor/alanning:roles';
import i18n from 'meteor/universe:i18n';
import { getLabel, checkDomain } from '../utils';
import { getLabel } from '../utils';
import checkDomain from '../domains';
import logServer from '../logging';
const AppRoles = ['candidate', 'member', 'animator', 'admin'];
......@@ -137,9 +139,9 @@ if (Meteor.isServer) {
const newUser = { ...user };
if (user.services && user.services.keycloak) {
/* eslint no-console:off */
console.log('Creating new user after Keycloak authentication :');
console.log(` Keycloak id: ${user.services.keycloak.id}`);
console.log(` email: ${user.services.keycloak.email}`);
logServer('Creating new user after Keycloak authentication :');
logServer(` Keycloak id: ${user.services.keycloak.id}`);
logServer(` email: ${user.services.keycloak.email}`);
newUser.emails = [{ address: user.services.keycloak.email, verified: true }];
}
if (options.firstName) newUser.firstName = options.firstName;
......@@ -194,7 +196,7 @@ if (Meteor.isServer) {
if (Meteor.settings.keycloak.adminEmails.indexOf(details.user.services.keycloak.email) !== -1) {
if (!Roles.userIsInRole(details.user._id, 'admin')) {
Roles.addUsersToRoles(details.user._id, 'admin');
console.log(i18n.__('api.users.adminGiven'), details.user.services.keycloak.email);
logServer(i18n.__('api.users.adminGiven'), details.user.services.keycloak.email);
}
}
} else {
......
......@@ -2,20 +2,6 @@ import { Meteor } from 'meteor/meteor';
import i18n from 'meteor/universe:i18n';
import SimpleSchema from 'simpl-schema';
// checks if the domain part of an email address matches whitelisted domains
export function checkDomain(email) {
let res = false;
const domainMail = email.split('@')[1];
const whiteDomains = Meteor.settings.private.whiteDomains || [];
whiteDomains.forEach((whiteDomain) => {
if (new RegExp(whiteDomain).test(domainMail)) {
console.log(` Email domain matches ${whiteDomain}: user activated`);
res = true;
}
});
return res;
}
export function isActive(userId) {
if (!userId) return false;
const user = Meteor.users.findOne(userId, { fields: { isActive: 1 } });
......
......@@ -5,6 +5,7 @@ import { ServiceConfiguration } from 'meteor/service-configuration';
// required: loads accounts customization before initial users creation
import faker from 'faker';
import logServer from '../../../api/logging';
import AppRoles from '../../../api/users/users';
import fakeData from './fakeData.json';
......@@ -28,13 +29,13 @@ if (Meteor.settings.keycloak) {
);
}
} else {
console.log('No Keycloak configuration. Please invoke meteor with a settings file.');
logServer('No Keycloak configuration. Please invoke meteor with a settings file.');
}
/* eslint-disable no-console */
function createUser(email, password, role, structure, firstName, lastName) {
console.log(` Creating user ${email}.`);
logServer(` Creating user ${email}.`);
const userID = Accounts.createUser({
username: email,
email,
......@@ -63,7 +64,7 @@ AppRoles.forEach((role) => {
const NUMBER_OF_FAKE_USERS = 300;
if (Meteor.users.find().count() === 0) {
if (Meteor.settings.private.fillWithFakeData) {
console.log('Creating the default user(s)');
logServer('Creating the default user(s)');
fakeData.defaultAccounts.map(({ email, password, role, structure, firstName, lastName }) =>
createUser(email, password, role, structure, firstName, lastName),
);
......@@ -82,6 +83,6 @@ if (Meteor.users.find().count() === 0) {
);
}
} else {
console.log('No default users to create ! Please invoke meteor with a settings file.');
logServer('No default users to create ! Please invoke meteor with a settings file.');
}
}
import { Meteor } from 'meteor/meteor';
import faker from 'faker';
import Articles from '../../../api/articles/articles';
import logServer from '../../../api/logging';
const users = (number) => {
const limit = Math.floor(Math.random() * number);
......@@ -13,13 +14,13 @@ if (Articles.find().count() === 0) {
if (Meteor.settings.private.fillWithFakeData && Meteor.isDevelopment) {
const PUBLISHERS_RANDOM = 100;
const publishers = users(PUBLISHERS_RANDOM);
console.log('Creating the default articles.');
logServer('Creating the default articles.');
publishers.forEach((userId) => {
const array = new Array(Math.floor(Math.random() * 30));
array.fill(0);
array.forEach(() => {
const title = faker.lorem.sentence();
console.log(`Creating article ${title} for user ${userId}.`);
logServer(`Creating article ${title} for user ${userId}.`);
Articles.insert({
userId,
title,
......
import { Meteor } from 'meteor/meteor';
import Categories from '../../../api/categories/categories';
import fakeData from './fakeData.json';
import logServer from '../../../api/logging';
function createCategorie(categorie) {
console.log(` Creating categorie ${categorie.name}.`);
logServer(` Creating categorie ${categorie.name}.`);
Categories.insert(categorie);
}
/** When running app for first time, pass a settings file to set up a default user account. */
if (Categories.find().count() === 0) {
if (Meteor.settings.private.fillWithFakeData) {
console.log('Creating the default categories');
logServer('Creating the default categories');
fakeData.defaultCategories.map((categorie) => createCategorie(categorie));
} else {
console.log('No default categories to create ! Please invoke meteor with a settings file.');
logServer('No default categories to create ! Please invoke meteor with a settings file.');
}
}
......@@ -5,6 +5,7 @@ import Groups from '../../../api/groups/groups';
import Services from '../../../api/services/services';
import { createGroup, favGroup } from '../../../api/groups/methods';
import fakeData from './fakeData.json';
import logServer from '../../../api/logging';
const users = (number) => {
const limit = Math.floor(Math.random() * number);
......@@ -21,7 +22,7 @@ const updatePersonalSpace = (usersList, groupId) => {
/** When running app for first time, pass a settings file to set up default groups. */
if (Groups.find().count() === 0) {
if (Meteor.settings.private.fillWithFakeData) {
console.log('Creating the default groups');
logServer('Creating the default groups');
fakeData.defaultGroups.map((group) => {
// find owner userId
const user = Meteor.users.findOne({ username: group.owner });
......@@ -29,9 +30,9 @@ if (Groups.find().count() === 0) {
const members = users(1000);
const candidates = group.type === 5 ? users(100) : [];
if (!user) {
console.log(`can not create group ${group.name}: owner not found in database`);
logServer(`can not create group ${group.name}: owner not found in database`);
} else {
console.log(` Creating group ${group.name}.`);
logServer(` Creating group ${group.name}.`);
if (Meteor.isDevelopment) {
const groupId = Groups.insert({
......@@ -79,7 +80,7 @@ if (Groups.find().count() === 0) {
const animators = users(ANIMATORS_RANDOM);
const members = users(MEMBERS_RANDOM);
const candidates = type === 5 ? users(CANDIDATES_RANDOM) : [];
console.log(` Creating group ${name}.`);
logServer(` Creating group ${name}.`);
const groupId = Groups.insert({
name,
type,
......@@ -104,6 +105,6 @@ if (Groups.find().count() === 0) {
});
}
} else {
console.log('No default groups to create ! Please invoke meteor with a settings file.');
logServer('No default groups to create ! Please invoke meteor with a settings file.');
}
}
import { Meteor } from 'meteor/meteor';
import PersonalSpaces from '../../../api/personalspaces/personalspaces';
import { updatePersonalSpace } from '../../../api/personalspaces/methods';
import logServer from '../../../api/logging';
// import fakeData from './fakeData.json';
// function createPersonalSpaces(personalspace) {
// const { userId } = personalspace; // in fakeData file, userId is set to user mail
// console.log(` Creating personalspace ${userId}.`);
// logServer(` Creating personalspace ${userId}.`);
// const user = Accounts.findUserByEmail(userId);
// PersonalSpaces.insert({ ...personalspace, userId: user._id });
// }
......@@ -13,10 +14,10 @@ import { updatePersonalSpace } from '../../../api/personalspaces/methods';
// /** When running app for first time, pass a settings file to set up a default user account. */
// if (PersonalSpaces.find().count() === 0) {
// if (Meteor.settings.private.fillWithFakeData) {
// console.log('Creating the default personalspaces');
// logServer('Creating the default personalspaces');
// fakeData.defaultPersonalSpaces.map(createPersonalSpaces);
// } else {
// console.log('No default personalspaces to create ! Please invoke meteor with a settings file.');
// logServer('No default personalspaces to create ! Please invoke meteor with a settings file.');
// }
// }
......@@ -25,7 +26,7 @@ if (Meteor.isDevelopment) {
const usersWithEmptyPS = PersonalSpaces.find({ unsorted: [], sorted: [] }, { fields: { userId: 1, _id: 0 } });
usersWithEmptyPS.forEach((user) => {
const u = Meteor.users.findOne({ _id: user.userId }, { fields: { username: 1, favServices: 1, favGroups: 1 } });
console.log(`Regen personalspaces for ${u.username}...`);
logServer(`Regen personalspaces for ${u.username}...`);
const unsorted = [];
u.favServices.forEach((s) => {
unsorted.push({
......
import { Meteor } from 'meteor/meteor';
import Services from '../../../api/services/services';
import fakeData from './fakeData.json';
import logServer from '../../../api/logging';
function createService(service) {
const { title } = service;
console.log(` Creating service ${title}.`);
logServer(` Creating service ${title}.`);
Services.insert(service);
}
/** When running app for first time, pass a settings file to set up a default user account. */
if (Services.find().count() === 0) {
if (Meteor.settings.private.fillWithFakeData) {
console.log('Creating the default services');
logServer('Creating the default services');
fakeData.defaultServices.map(createService);
} else {
console.log('No default services to create ! Please invoke meteor with a settings file.');
logServer('No default services to create ! Please invoke meteor with a settings file.');
}
}
......@@ -3,7 +3,7 @@ export default function notificationSystem(title, options) {
// eslint-disable-next-line
const notification = new Notification(title, options);
} else if (Notification.permission !== 'denied') {
Notification.requestPermission(function (permission) {
Notification.requestPermission(function notifySystem(permission) {
if (!('permission' in Notification)) {
Notification.permission = permission;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment