Skip to content

Commit

Permalink
Merge pull request #90 from Arquisoft/documentation-1.1-sara
Browse files Browse the repository at this point in the history
Documentation - Part 6 checked
  • Loading branch information
uo276670 authored Apr 9, 2023
2 parents e4ec38e + 853675f commit 3be781f
Show file tree
Hide file tree
Showing 14 changed files with 491 additions and 18 deletions.
2 changes: 1 addition & 1 deletion docs/02_architecture_constraints.adoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[[section-architecture-constraints]]
== Architecture Constraints
=== Technical constraints
Use of SOLID pods:: The user’s information must be secured and stored in personal SOLID pods.
Use of SOLID PODs:: The user’s information must be secured and stored in personal SOLID pods.
Use of Git:: The version control of the project must be done using Git.

=== Organizational constraints
Expand Down
6 changes: 4 additions & 2 deletions docs/04_solution_strategy.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,23 @@ Refer to details in the following sections.
=== Technology decisions
This are the technologies that we have decided to use, some of them may vary in future iterations of the poyect:

* SOLID Pods for security
* SOLID PODs for security
* TypeScript as programming language
* MongoDb as our DMBS
* Redux using React as UI
* Axios
* Postman
* Chakra UI (for the implementation of the views)


=== Design decisions:
The general design of our project has two main parts, connected using a facade:

* Webapp (frontend): It has different views, it connects to the SOLID pods to acess user's data in an secure way, and it communicates with the backend using a facade
* Webapp (frontend): It has different views, it connects to the SOLID PODs to acess user's data in an secure way, and it communicates with the backend using a facade
* RestAPI (backend): controls the acess to the database and communicates with the frontend using the facade



=== Quality decisions
The main quality attributes that we will focus on are the following:
[options="header",cols="1,2,2"]
Expand Down
22 changes: 9 additions & 13 deletions docs/06_runtime_view.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -30,41 +30,37 @@ There are many notations for describing scenarios, e.g.
****

=== User registration
* The user enters the system for the first time and registers their personal data to create an account and start ussing the webapp.
** The user will be able to fill a form with their data that is saved on their private POD.


=== User Login
* The user already registered on the system and wants to log in with their user and password to acess the webapp.
** The user will be able to fill a form with their user and password that will be sent to the server to be authenticated and allow or deny access.
* The user wants to log in with their POD to acess the webapp.
** The user will be able to fill a form that will redirect him to its POD's provider in order to give the application access to its POD's information or deny it.


=== Adding a Location
* The user wants to add the location restaurant to the webapp and see it on the map.
** The user will be able to select a location category and the coordinates for the location to be placed and seen on their map and it will be saved on their POD.
** The user will click on a place on the map and a form will be displayed where the user will be able to select a location category and the name for the location to be placed and seen on their map and it will be saved on their POD.


=== Reviewing information about a place
=== Reviewing information about a place (Not implemented yet)
* The user wants to select a friend's added location and see the pictures they added to it.
** Locations made public or shared with the user will be able to be accesed by the user to review aditional information that the creator added to the place.


=== Changing privacy settings
=== Changing privacy settings (Not implemented yet)
* The user doesn't want their friends seeing the locations she added to the map so they acess the settings of the webapp to disable sharing them.
** The different settings about what information on the places and the user is accesible by their friends will be able to be changed, giving different options for each parameter.


=== Adding a new friend
* A user navigating the app wants to search and add a concrete friend to their friend list.
** The user will be able to write the user of a friend that, if in the database, will be added to their personal friend list and the connection stored on the database.
** The user will be able to write the WebId of a friend's POD and also a NickName just to be similar to an agenda.


=== Deleting a friend
=== Deleting a friend (Not implemented yet)
* A user wants to remove a friend from their friend list.
** The user will be given the option to remove a frient from their list, if they do the system wont consider them a friend and all places shared with them will no longer be shared.
** The user will be given the option to remove a friend from their list, if they do the system wont consider them a friend and all places shared with them will no longer be shared.


=== Creating a friend group
=== Creating a friend group (Not implemented yet)
* The user wants to create a group of friends and manage privacy on the group.
** The group of friends will be treated as a single friend, after creation it will be stored on the database and the information that is shared or not will affect the whole group.
4 changes: 2 additions & 2 deletions docs/10_quality_scenarios.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ image:10-QualityRequirements/Quality-tree.png["Quality tree diagram"]

| Privacy
| We need to protect the user's data. The application will only take essential data from users and it will be done in a decentralized way.
| User's data will be retrieved from the user's pod.
| User's data will be retrieved from the user's POD.
| High


Expand All @@ -39,6 +39,6 @@ image:10-QualityRequirements/Quality-tree.png["Quality tree diagram"]

| Decentralization
| Decentralization of the log in process (serverless).
| It is achieved by means of calling the Pod provider and delegating the process to it.
| It is achieved by means of calling the POD provider and delegating the process to it.
| High
|===
35 changes: 35 additions & 0 deletions restapi/build/builders/locationBuilder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildTestLocationThing = exports.locationToThing = exports.thingToLocation = void 0;
const solid_client_1 = require("@inrupt/solid-client");
const vocab_common_rdf_1 = require("@inrupt/vocab-common-rdf");
function thingToLocation(locationThing) {
return {
id: locationThing.url,
name: (0, solid_client_1.getStringNoLocale)(locationThing, vocab_common_rdf_1.SCHEMA_INRUPT.name),
locationType: (0, solid_client_1.getStringNoLocale)(locationThing, vocab_common_rdf_1.SCHEMA_INRUPT.description),
latitude: (0, solid_client_1.getDecimal)(locationThing, vocab_common_rdf_1.SCHEMA_INRUPT.latitude),
longitude: (0, solid_client_1.getDecimal)(locationThing, vocab_common_rdf_1.SCHEMA_INRUPT.longitude)
};
}
exports.thingToLocation = thingToLocation;
function locationToThing(location) {
return (0, solid_client_1.buildThing)((0, solid_client_1.createThing)({ name: location.name }))
.addStringNoLocale(vocab_common_rdf_1.SCHEMA_INRUPT.name, location.name)
.addStringNoLocale(vocab_common_rdf_1.SCHEMA_INRUPT.description, location.locationType)
.addDecimal(vocab_common_rdf_1.SCHEMA_INRUPT.latitude, location.latitude)
.addDecimal(vocab_common_rdf_1.SCHEMA_INRUPT.longitude, location.longitude)
.addUrl(vocab_common_rdf_1.RDF.type, "https://schema.org/Place")
.build();
}
exports.locationToThing = locationToThing;
function buildTestLocationThing() {
return (0, solid_client_1.buildThing)((0, solid_client_1.createThing)({ name: "Location2" }))
.addStringNoLocale(vocab_common_rdf_1.SCHEMA_INRUPT.name, 'nuevaLocalizacion2')
.addStringNoLocale(vocab_common_rdf_1.SCHEMA_INRUPT.description, "bar")
.addDecimal(vocab_common_rdf_1.SCHEMA_INRUPT.latitude, 1)
.addDecimal(vocab_common_rdf_1.SCHEMA_INRUPT.longitude, 2)
.addUrl(vocab_common_rdf_1.RDF.type, "https://schema.org/Place")
.build();
}
exports.buildTestLocationThing = buildTestLocationThing;
11 changes: 11 additions & 0 deletions restapi/build/locationType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocationType = void 0;
var LocationType;
(function (LocationType) {
LocationType["shop"] = "shop";
LocationType["bar"] = "bar";
LocationType["restaurant"] = "restaurant";
LocationType["sight"] = "sight";
LocationType["monument"] = "monument";
})(LocationType = exports.LocationType || (exports.LocationType = {}));
105 changes: 105 additions & 0 deletions restapi/build/podsAccess/authenticationService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const solid_client_authn_node_1 = require("@inrupt/solid-client-authn-node");
exports.default = {
initLogin: function (req, res) {
return __awaiter(this, void 0, void 0, function* () {
// create a new Session
const session = new solid_client_authn_node_1.Session();
req.session.solidSessionId = session.info.sessionId;
console.log(req.query.providerURL);
console.log(req.session.solidSessionId);
//Redirect user to POD provider login
const redirectToSolidIdentityProvider = (providerURL) => {
res.redirect(providerURL);
};
// redirect handler will handle sending the user to their POD Provider.
yield session.login({
// If login successfully, redirect here
redirectUrl: 'http://localhost:8082/auth/loginconfirm',
// Set user SOLID identity provider
oidcIssuer: req.query.providerURL,
//oidcIssuer: "https://login.inrupt.com",
// Application name to show when requesting data
clientName: "LoMap",
//handler to redirect to the provider login
handleRedirect: redirectToSolidIdentityProvider
});
});
},
confirmLogin: function (req, res) {
return __awaiter(this, void 0, void 0, function* () {
// If we get here, the user has logged in successfully
// Recover session information
const session = yield (0, solid_client_authn_node_1.getSessionFromStorage)(req.session.solidSessionId);
// Complete login process using the data appended by the Solid Identity Provider
try {
yield session.handleIncomingRedirect(`http://localhost:8082/auth${req.url}`);
}
catch (e) {
console.log(e);
return res.sendStatus(500);
}
// Session now contains an authenticated Session instance.
if (session.info.isLoggedIn) {
return res.redirect("http://localhost:3000/login/confirm");
}
return res.sendStatus(401);
});
},
logout: function (req, res) {
return __awaiter(this, void 0, void 0, function* () {
const session = yield (0, solid_client_authn_node_1.getSessionFromStorage)(req.session.solidSessionId);
yield session.logout();
res.redirect("http://localhost:3000");
});
},
initTestLogin: function (req, res) {
return __awaiter(this, void 0, void 0, function* () {
// create a new Session
const session = new solid_client_authn_node_1.Session();
req.session.solidSessionId = session.info.sessionId;
console.log(req.session.solidSessionId);
//Redirect user to POD provider login
const redirectToSolidIdentityProvider = (providerURL) => {
res.redirect(providerURL);
};
// redirect handler will handle sending the user to their POD Provider.
yield session.login({
// If login successfully, redirect here
redirectUrl: 'http://localhost:8082/auth/testloginconfirm',
// Set user SOLID identity provider
oidcIssuer: "https://login.inrupt.com",
// Application name to show when requesting data
clientName: "LoMap",
//handler to redirect to the provider login
handleRedirect: redirectToSolidIdentityProvider
});
});
},
confirmTestLogin: function (req, res) {
return __awaiter(this, void 0, void 0, function* () {
// If we get here, the user has logged in successfully
// Recover session information
console.log(req.session.solidSessionId);
const session = yield (0, solid_client_authn_node_1.getSessionFromStorage)(req.session.solidSessionId);
// Complete login process using the data appended by the Solid Identity Provider
yield session.handleIncomingRedirect(`http://localhost:8082/auth${req.url}`);
console.log(session === null || session === void 0 ? void 0 : session.info.webId);
// Session now contains an authenticated Session instance.
if (session.info.isLoggedIn) {
return res.redirect("http://localhost:3000");
}
return res.send("Not able to log in");
});
},
};
90 changes: 90 additions & 0 deletions restapi/build/podsAccess/locationsService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const solid_client_1 = require("@inrupt/solid-client");
const solid_client_authn_node_1 = require("@inrupt/solid-client-authn-node");
const locationBuilder_1 = require("../builders/locationBuilder");
const locationValidator_1 = require("../validators/locationValidator");
exports.default = {
saveLocation: function (req, res) {
return __awaiter(this, void 0, void 0, function* () {
console.log("saving location");
console.log(req.session.solidSessionId);
const session = yield (0, solid_client_authn_node_1.getSessionFromStorage)(req.session.solidSessionId);
if (session == undefined) {
console.log("not valid session");
return res.send('error');
}
let locationsURL = yield getLocationsURL(session.info.webId);
if (locationsURL == undefined) {
console.log("error accessing the pod");
return res.send("error");
}
let location = req.body.location;
console.log(req.body);
if (!(0, locationValidator_1.validateLocation)(location)) {
console.log("not valid location");
console.log(location);
res.send('error');
}
let locationsSolidDataset = yield (0, solid_client_1.getSolidDataset)(locationsURL, { fetch: session.fetch } // fetch from authenticated session
);
const locationThing = (0, locationBuilder_1.locationToThing)(location);
locationsSolidDataset = (0, solid_client_1.setThing)(locationsSolidDataset, locationThing);
let newDataset = yield (0, solid_client_1.saveSolidDatasetAt)(locationsURL, locationsSolidDataset, { fetch: session.fetch } // fetch from authenticated Session
);
console.log("location saved");
return res.send((0, solid_client_1.getThingAll)(newDataset).map(locationThing => (0, locationBuilder_1.thingToLocation)(locationThing)));
});
},
getOwnLocations: function (req, res) {
return __awaiter(this, void 0, void 0, function* () {
const session = yield (0, solid_client_authn_node_1.getSessionFromStorage)(req.session.solidSessionId);
if (session == undefined)
return res.send('error');
let locationsURL = yield getLocationsURL(session.info.webId);
if (locationsURL == undefined)
return res.send("error");
let locationsDataset = yield (0, solid_client_1.getSolidDataset)(locationsURL, { fetch: session.fetch } // fetch from authenticated session
);
return res.send((0, solid_client_1.getThingAll)(locationsDataset)
.filter(locationThing => (0, locationValidator_1.validateLocationThing)(locationThing))
.map(locationThing => (0, locationBuilder_1.thingToLocation)(locationThing)));
});
},
saveTestLocation: function (req, res) {
return __awaiter(this, void 0, void 0, function* () {
const session = yield (0, solid_client_authn_node_1.getSessionFromStorage)(req.session.solidSessionId);
if (session == undefined)
return res.send('error');
let locationsURL = yield getLocationsURL(session.info.webId);
if (locationsURL == undefined)
return res.send("error");
const locationThing = (0, locationBuilder_1.buildTestLocationThing)();
let locationsSolidDataset = yield (0, solid_client_1.getSolidDataset)(locationsURL, { fetch: session.fetch } // fetch from authenticated session
);
locationsSolidDataset = (0, solid_client_1.setThing)(locationsSolidDataset, locationThing);
let newDataset = yield (0, solid_client_1.saveSolidDatasetAt)(locationsURL, locationsSolidDataset, { fetch: session.fetch } // fetch from authenticated Session
);
return res.send((0, solid_client_1.getThingAll)(newDataset).map(locationThing => (0, locationBuilder_1.thingToLocation)(locationThing)));
});
}
};
function getLocationsURL(webId) {
return __awaiter(this, void 0, void 0, function* () {
if (webId == undefined)
return undefined;
let webID = decodeURIComponent(webId);
const podURL = yield (0, solid_client_1.getPodUrlAll)(webID);
console.log(podURL);
return podURL + "private/";
});
}
Loading

0 comments on commit 3be781f

Please sign in to comment.