• Rezultati Niso Bili Najdeni

Spletnaaplikacijazaskavtskoorganizacijo BlaˇzSkoˇcir

N/A
N/A
Protected

Academic year: 2022

Share "Spletnaaplikacijazaskavtskoorganizacijo BlaˇzSkoˇcir"

Copied!
74
0
0

Celotno besedilo

(1)

Univerza v Ljubljani

Fakulteta za raˇ cunalniˇ stvo in informatiko

Blaˇz Skoˇcir

Spletna aplikacija za skavtsko organizacijo

DIPLOMSKO DELO

VISOKOˇSOLSKI STROKOVNI ˇSTUDIJSKI PROGRAM PRVE STOPNJE

RA ˇCUNALNIˇSTVO IN INFORMATIKA

Mentor : dr. Aleˇs Smrdel

Ljubljana, 2022

(2)

koriˇsˇcenje rezultatov diplomske naloge je potrebno pisno privoljenje avtorja, Fakultete za raˇcunalniˇstvo in informatiko ter mentorja.

Besedilo je oblikovano z urejevalnikom besedil LATEX.

(3)

Fakulteta za raˇcunalniˇstvo in informatiko izdaja naslednjo nalogo:

Tematika naloge:

V Sloveniji in po svetu obstaja veliko raznih organizacij z dolgoletno tra- dicijo. Navkljub dolgi tradiciji pa tudi te organizacije za laˇzje upravljanje in sodelovanje uvajajo ali pa ˇze uporabljajo spletne aplikacije. Ena izmed teh organizacij je tudi skavtska organizacija. V okviru diplome je vaˇsa na- loga, da za potrebe organizacije, komunikacije, obveˇsˇcanja in sodelovanja med ˇclani skavtske organizacije implementirate spletno aplikacijo. Pri naˇcrtovanju aplikacije preuˇcite organiziranost organizacije ter nujne funkcionalnosti. De- finirajte tudi ustrezno shemo podatkovne baze ter potrebne vloge uporab- nikov, ki bodo odraˇzale organiziranost, in njihove pravice. Nato razvijte tudi streˇzniˇski in odjemalski del aplikacije. Pri razvoju aplikacije izberite in uporabite tiste tehnologije na strani streˇznika in odjemalca, ki omogoˇcajo implementacijo dobre uporabniˇske izkuˇsnje.

(4)
(5)

Zahvaljujem se mentorju dr. Aleˇsu Smrdel za njegovo odzivnost in usmeritve.

Zahvaljujem se tudi vsem, ki so me tekom ˇstudija spodbujali in mi pomagali.

(6)
(7)

Svoji dragi Lei.

(8)
(9)

Kazalo

Povzetek Abstract

1 Uvod 1

1.1 Struktura skavtske organizacije . . . 2

1.2 Cilji . . . 3

1.3 Pregled podroˇcja . . . 3

1.4 Struktura diplomske naloge . . . 4

2 Uporabljene tehnologije 5 2.1 HTML . . . 5

2.2 CSS . . . 6

2.3 JavaScript . . . 6

2.4 Angular . . . 6

2.5 Laravel . . . 7

2.6 PostgreSQL . . . 8

2.7 WebSocket . . . 8

3 Razvoj aplikacije 9 3.1 Arhitektura . . . 9

3.2 Podatkovna baza . . . 10

3.2.1 Predloge skupin . . . 10

3.2.2 Drevesna struktura skupin . . . 13

(10)

3.3.1 Avtentikacija . . . 23

3.3.2 Sistem povabil . . . 26

3.3.3 Komunikacija in obveˇsˇcanje . . . 33

3.4 Uporabniˇski vmesnik . . . 39

3.4.1 Lokalno stanje aplikacije . . . 40

3.4.2 Preverjanje uporabnikovih pravic . . . 42

3.4.3 Posodobitve v realnem ˇcasu . . . 44

4 Predstavitev aplikacije 49 4.1 Komunikacija in obveˇsˇcanje . . . 49

4.2 Ustvarjanje in pregled dogodkov . . . 50

4.3 Dodajanje in pregled ˇclanov . . . 52

5 Zakljuˇcek 55 5.1 Nadaljnje delo . . . 56

(11)

Seznam uporabljenih kratic

kratica angleˇsko slovensko

HTML Hypertext Markup Language Jezik za oznaˇcevanje nadbese- dila

CSS Cascading Style Sheet Kaskadna stilska predloga SPA Single-Page Application Enostranska aplikacija PHP Hypertext Preprocessor Nadbesedilni preprocesor MVC Model-View-Controller Model-Pogled-Kontroler ORDBMS Object-Relational Database

Management Sistem

Objektno-relacijski sistem za upravljanje s podatkovnimi bazami

ORM Object-relational mapping Objektno-relacijsko mapiranje MPA Multiple-page application Veˇcstranska aplikacija

TCP Transmission Control Protocol Protokol za nadzor prenosa HTTP Hypertext Transfer Protocol Protokol za prenos nadbesedila API Application Programming In-

terface

Aplikacijski programski vme- snik

JSON JavaScript Object Notation Objektna notacija JavaScript SMS Short Message Service Sistem kratkih sporoˇcil GSM Global System for Mobile com-

munications

Globalni sistem za mobilno ko- munikacijo

(12)
(13)

Povzetek

Naslov: Spletna aplikacija za skavtsko organizacijo Avtor: Blaˇz Skoˇcir

Namen diplomske naloge je bil razvoj spletne aplikacije, ki ˇclanom znotraj skavtske organizacije poenostavi in poenoti komunikacijo, obveˇsˇcanje in so- delovanje. Cilj aplikacije je nadomestiti veˇc storitev, ki se trenutno upora- bljajo za ta namen. Preko spletnega vmesnika, narejenega v ogrodju Angu- lar, lahko ˇclani med seboj komunicirajo z uporabo realnoˇcasovnega klepeta, ogledujejo aktivne dogodke ter prejemajo razna obvestila. Vodilnim ˇclanom pa omogoˇca tudi, da s svojimi ˇclani laˇzje in uˇcinkovito upravljajo, z njimi komunicirajo in jih obveˇsˇcajo preko objavljanja obvestil. Spletni vmesnik pri- dobiva podatke preko podatkovnega vmesnika narejenega v ogrodju Laravel.

Za realnoˇcasovne posodobitve vsebine pa se uporablja komunikacijski proto- kol WebSocket. Razvita spletna aplikacija je bila dobro sprejeta in zadostuje ciljem, ki smo si jih zadali na zaˇcetku razvoja.

Kljuˇcne besede: programiranje, angular, laravel, postgresql, spa, spletna aplikacija, splet, skavti.

(14)
(15)

Abstract

Title: Web application for scouts organization Author: Blaˇz Skoˇcir

Thee aim of this diploma thesis was the development of a web application that simplifies and unifies communication, informing and cooperation for members of scouts organization. The goal of the web application is to replace several services currently used for this purpose. Through the web interface created with the Angular framework, members can communicate with each other using real-time chat, view active events and receive various notifications. It also enables leading members to easily and efficiently manage, communicate and inform their members through posts. The web interface retrieves data via an application programming interface developed with Laravel framework.

To achieve real-time data updates, the WebSocket communication protocol is used. The developed web application was well accepted and achieved the goals set at the beginning of the development.

Keywords: programming, angular, laravel, postgresql, spa, web application, web, scouts.

(16)
(17)

Poglavje 1 Uvod

Dandanes organizacije, druˇstva in razne druge skupine uporabljajo digitalne reˇsitve za organizacijo in komuniciranje. To omogoˇca uporabo raznih elek- tronskih naprav, od namiznih raˇcunalnikov do mobilnih pametnih telefonov.

Poleg tega te reˇsitve tudi omogoˇcajo dosegljivost podatkov vedno in povsod.

Veˇcinoma so tovrstne digitalne reˇsitve narejene tako, da reˇsijo specifiˇcen pro- blem. Obstajajo tudi orodja, ki reˇsijo veˇc problemov oziroma so narejena, da jih lahko prilagodimo na svoj problem. V primerih, ko ne obstaja orodje, ki nam reˇsi vse probleme, smo primorani uporabljati veˇc razliˇcnih orodij oziroma implementirati lastno reˇsitev, ki bo prilagojena vsem zahtevam spe- cifiˇcnega problema.

Namen te diplomske naloge je izdelati spletno aplikacijo, ki bi za zaˇcetek zdruˇzila in poenotila organizacijo, komunikacijo in obveˇsˇcanje med ˇclani skavtske organizacije. Za razvoj in oblikovanje reˇsitev moramo poznati struk- turo skavtske organizacije, ki je predstavljena v podpoglavju 1.1. To nam omogoˇca, da doloˇcimo strukturo in relacije podatkov, potrebne vloge v sis- temu in tudi nujne funkcionalnosti, ki morajo biti implementirane za osnovno delovanje.

1

(18)

1.1 Struktura skavtske organizacije

Vsak skavt pripada skavtski skupini, imenovani skavtska lokalna enota ali steg. Stegi se povezujejo v obmoˇcja, imenovana ognjiˇsˇca. Naloga ognjiˇsˇca je, da spremlja ter spodbuja razvoj in dejavnost stegov. Vsak steg ima ˇclane, ki so razdeljeni v starostne skupine, imenovane veje. Veje so popotniki in popotnice (PP), izvidniki in vodnice (IV), volˇciˇci in volkuljice (VV), bobri in bobrovke (BB) ter skupnost voditeljev (SKVO). SKVO je skupina, name- njena voditeljem vej. ˇClani so v vejah razdeljeni v ˇse manjˇse skupine. Na primer v veji IV so te skupine imenovane vodi. V vsaki zgoraj omenjeni sku- pini imajo ˇclani vloge. Steg ima stegovodjo, blagajnika, delegata ..., veja ima voditelja veje, voditelje ..., vsak vod ima vodnika, podvodnika, zastavonoˇso, kuharja itd. Vsak ˇclan ima vsaj eno vlogo. Slika 1.1 prikazuje poenostavljeno strukturo skavtske organizacije.

Slika 1.1: Struktura skavtske organizacije

(19)

Diplomska naloga 3

1.2 Cilji

Cilj te diplomske naloge je narediti enostransko spletno aplikacijo, ki bo skavtom olajˇsala organizacijo, komunikacijo ter obveˇsˇcanje. Ker je aplikacija namenjena samo ˇclanom skavtske organizacije in ne sploˇsni populaciji, je tudi pomembno, kako se ustvarjajo skupine ter dodajajo ˇclani, saj struktura naraˇsˇca s prihajanjem novih ˇclanov. Najprej bo stegovodja dodan v svoj steg. Kot vodja stega bo imel pravice ustvarjati veje in dodajati nove ˇclane.

Vsak ˇclan bo imel pregled nad svojimi skupinami, dogodki in soˇclani. V vsaki skupini bo na voljo skupinski klepet, kjer bo potekala komunikacija med ˇclani skupine. Voditelj bo lahko ˇclanom dodeljeval in odstranjeval vloge, z njimi komuniciral ter jih obveˇsˇcal in ustvarjal dogodke.

1.3 Pregled podroˇ cja

Skavtska organizacija ima ˇze narejen spletni portal, preko katerega lahko le vodilni ˇclani med seboj komunicirajo ter upravljajo in si ogledujejo ˇclane svojih stegov. Portal pa ne omogoˇca komuniciranja znotraj stega, ki je za uˇcinkovito delovanje skupine kljuˇcnega pomena. Za organizacijo dela in spro- tno obveˇsˇcanje znotraj stega se pogosto uporabljajo druge storitve, kot so Fa- cebook skupine in klepet, SMS obveˇsˇcanje, Google Drive za deljenje datotek, Zoom za videoklice ipd.

(20)

1.4 Struktura diplomske naloge

Diplomska naloga je razdeljena na tri glavna poglavja. V poglavju Upo- rabljene tehnologije so predstavljene tehnologije, ki so bile uporabljene pri razvoju spletne aplikacije. Diploma se nadaljuje s poglavjem Razvoj apli- kacije, ki je razdeljeno na dva dela. V prvem delu je predstavljen razvoj zalednega sistema, v drugem delu pa razvoj spletnega vmesnika. Zadnje glavno poglavje je Predstavitev aplikacije, kjer so predstavljeni konˇcni iz- gled in funkcionalnosti, ki jih spletna aplikacija ponuja. Diplomska naloga se zakljuˇci z ugotovitvami in razmislekom o nadaljnjem delu.

(21)

Poglavje 2

Uporabljene tehnologije

V tem poglavju so opisana orodja in tehnologije, ki so bile uporabljene pri razvoju.

2.1 HTML

HTML [5, 6, 8] je opisni jezik, s katerim opiˇsemo strukturo spletne strani.

Strukturo opiˇsemo z uporabo znaˇck in atributov, ki doloˇcajo HTML elemente v strukturi in njihove lastnosti. Veˇcina elementov je sestavljena iz zaˇcetne in konˇcne znaˇcke, med katerima se nahaja vsebina. Vsak element ima svoj pomen, s katerim opiˇse del spletne strani. Spletne strani si ogledujemo v brskalnikih, saj poznajo veˇcino elementov in vedo, kako jih prikazati. Na primer znaˇcka <strong> pove, da je besedilo znotraj elementa pomembno in ga bo brskalnik prikazal kot odebeljeno besedilo. Znaˇcka <p> opiˇse besedilo znotraj elementa kot odstavek. Vsakemu elementu oziroma zaˇcetni znaˇcki lahko dodamo atribute, ki element ˇse dodatno opiˇsejo in mu dodajo lastnosti. Na primer, eden izmed atributov jeclass, ki elementu doloˇci, kateri CSS razredi bodo zanj veljali. HTML je najbolj osnovna tehnologija za izdelovanje spletnih strani.

5

(22)

2.2 CSS

CSS [2] so pravila, zapisana s preprostim slogovnim jezikom, s katerimi doloˇcimo, kako bodo HTML elementi, ki sestavljajo spletno stran, izgledali.

Vsakemu HTML elementu lahko doloˇcimo atribut, ki sluˇzi kot unikatno iden- tifikacijsko ime, na katero se v CSS predlogi sklicujemo, ko opisujemo izgled elementa. Na voljo imamo tudi tako imenovane razrede, ki jih v CSS predlogi definiramo in uporabimo na veˇc elementih v HTML dokumentu. V sklopu diplomske naloge uporabljamo ogrodje Tailwind [15], ki nam ponuja velik izbor ˇze definiranih CSS razredov, s katerimi ˇzeli pokriti ˇcim veˇc primerov uporabe. S tem smo prihranili ˇcas, saj nam ni treba pisati svojih predlog.

2.3 JavaScript

JavaScript [4, 7] je skriptni jezik, ki zna upravljati s HTML elementi. Izvaja se znotraj brskalnika. Namen jezika je, da z manipuliranjem elementov naredi stran bolj interaktivno. JavaScript lahko ustvarja, ureja in briˇse HTML ele- mente, ki sestavljajo HTML strukturo strani. Stran postane bolj dinamiˇcna in s tem se izboljˇsa uporabniˇska izkuˇsnja. Uporablja se za validacijo forme, animacije ipd. Razvilo ga je podjetje Netscape kot razˇsiritev opisnemu je- ziku HTML. Dandanes imamo orodja, kot so NodeJS, Deno ipd., ki nam omogoˇcajo uporabo JavaScript kot samostojnega programskega jezika izven okolja brskalnika.

2.4 Angular

Angular [1] je odprtokodno spletno ogrodje, napisano v jeziku TypeScript.

Razvil ga je Google in je nadgradnja prvotnega AngularJS ogrodja. Type- Script [11] je objektno usmerjen programski jezik, ki ga razvija in vzdrˇzuje Microsoft. Je nadmnoˇzica skriptnega jezika JavaScript, ki mu doda preddefi- nirane tipe podatkov, vmesnike, razrede, enume, module in druge strukture,

(23)

Diplomska naloga 7 s ˇcimer nam olajˇsa razvoj in vzdrˇzevanje aplikacij. Na TypeScript lahko gle- damo kot na sistem za tipizacijo, ki ga s pridom lahko uporabljamo samo v razvijalnih okoljih, saj se kasneje prevede v JavaScript, ki ga brskalniki ra- zumejo in znajo izvajati. Angular se uporablja za razvijanje spletnih strani, imenovanih enostranske aplikacije (angl. Single-page application, SPA) [3].

Sploˇsno gledano pa je Angular aplikacija sestavljena iz HTML predlog, kom- ponent in storitev. Komponenta pridobi podatke z uporabo storitve, jih po potrebi obdela in prikaˇze z uporabo HTML predloge. Prednost takih apli- kacij je, da so bolj odzivne, saj se ne naloˇzijo pri vsaki zahtevi. Ena izmed prednosti Angularja je, da vkljuˇcuje vse potrebno za razvijanje velikih apli- kacij, poleg tega pa sta proces razvijanja ter arhitektura aplikacije doloˇcena, kar nam olajˇsa razvoj.

2.5 Laravel

Laravel [9] je brezplaˇcno odprtokodno PHP ogrodje, namenjeno razvoju sple- tnih aplikacij. Razvil ga je Taylor Otwell leta 2011. Arhitektura ogrodja sledi razvijalskemu vzorcu Model-Pogled-Kontroler (angl. Model-View-Controller, MVC). Model predstavlja podatkovno entiteto, preko katere kontroler prido- biva in shranjuje podatke. Po obdelavi podatkov jih preda pogledu, kjer je v HTML-ju definirano, kako se prikaˇzejo. Laravel poskuˇsa z velikim nabo- rom storitev poenostaviti ter pohitriti razvoj aplikacij. Primer storitve je poˇsiljanje e-sporoˇcil, oddajanje (WebSocket), migracije, ˇcakalne vrste, ORM ipd. ORM [12] je abstrakcija interakcije s podatkovno bazo. Omogoˇca po- izvedovanje in shranjevanje v podatkovno bazo preko modelov. Laravel je bil sprva namenjen razvoju klasiˇcnih veˇcstranskih spletnih aplikacij (angl.

Multiple-Page Application, MPA), danes pa ga lahko preko composer pa- keta Sanctum uporabimo tudi kot podatkovni vmesnik - API. Composer je upravitelj odvisnosti (angl. dependency manager) med paketi PHP.

(24)

2.6 PostgreSQL

PostgreSQL [13] ali Postgres je brezplaˇcen odprtokodni sistem za upravlja- nje objektno-relacijskih podatkovnih baz (angl. ORDBMS). Je predvsem relacijska podatkovna baza podatkov, ki podpira nekatere objektno usmer- jene funkcionalnosti. Primeri objektno orientiranih funkcionalnosti so upo- rabniˇsko definirani podatkovni tipi, dedovanje med tabelami ipd. Postgres je skladen s strukturiranim povpraˇsevalnim jezikom za delo s podatkovnimi bazami (angl. Structured Query Language, SQL). SQL [14] omogoˇca z upo- rabo jezika podobnega naravnemu kreiranje, branje, brisanje in posodablja- nje tabel. Podatke v tabelah med seboj logiˇcno povezujemo, poizvedujemo, briˇsemo in posodabljamo.

2.7 WebSocket

WebSocket [16] je komunikacijski protokol, ki omogoˇci dvosmerno komunika- cijo med streˇznikom in odjemalcem (brskalnik). Komunikacija poteka preko niˇzjenivojskega protokola TCP. Povezavo inicializira odjemalec z GET zah- tevno na streˇznik. Po zahtevi se protokol HTTP zamenja z WebSocket.

Protokol se najpogosteje uporablja v SPA za aktivnosti, ki zahtevajo ko- munikacijo v realnem ˇcasu. Primeri uporabe so spletni pogovor, obvestila ipd.

(25)

Poglavje 3

Razvoj aplikacije

V tem poglavju je opisan razvoj aplikacije. V vsakem podpoglavju je opisana implementacija doloˇcenih funkcij, ki so pomembnejˇse za samo reˇsitev.

3.1 Arhitektura

Aplikacijo sestavlja veˇc delov, ki so med seboj odvisni in med seboj sodelujejo.

Arhitektura aplikacije je okolje, v katerem ˇzivi. Prednji del (angl. frontend) spletne aplikacije je Angular aplikacija, ki predstavlja grafiˇcni videz in edino, kar je vidno konˇcnemu uporabniku. Ko uporabnik zahteva doloˇceno akcijo, ki je lahko prijava, prikaz nove strani, pridobivanje doloˇcenih podatkov ipd.

Angular poˇslje zahtevo na streˇznik, kjer ˇzivi zaledni sistem (angl. backend).

V naˇsem primeru je to Laravel aplikacija. Njegova naloga je, da naˇso zahtevo sprejme, obdela ter nanjo odgovori. Ko na primer prejme zahtevo za prijavo, skupaj z uporabniˇskim imenom in geslom, mora preveriti, ali je geslo za vneseno uporabniˇsko ime pravilno. Za to potrebuje podatkovno bazo, kjer so shranjena vsa uporabniˇska imena in gesla. Podatkovna baza je zadnji sestavni del naˇse spletne aplikacije. V bazi so shranjeni podatki, ki so potrebni za delovanje aplikacije. Primeri takih podatkov so na primer: ime uporabnikov, gesla, datum rojstva, ˇclanstvo skupin ipd. Prednji del prikazuje podatke uporabniku, zaledni sistem jih obdeluje, ureja in filtrira, podatkovna baza

9

(26)

jih hrani.

3.2 Podatkovna baza

Poenostavljeno gledano je podatkovna baza velika shramba logiˇcno pove- zanih podatkov. Sestavljena je iz sheme, ki podatkovno bazo opisuje, in fiziˇcnih podatkov na disku. Shema je opis strukture podatkov in opredeli vsa moˇzna stanja podatkovne baze. Definira se enkrat, ko se podatkovna baza ustvari, lahko pa se kasneje ˇse spreminja. Za pridobivanje, brisanje in ure- janje podatkov potrebujemo sistem za upravljanje podatkovne baze (SUPB, ang. Relational Database Management System). SUPB, ki ga uporabljamo za naˇso aplikacijo, se imenuje Postgresql (podpoglavje 2.6).

Podatkovno bazo bi lahko ustvarili s pomoˇcjo raznih orodij, ki iz logiˇcnega modela zgenerirajo SQL kodo in ustvarijo bazo. Lahko pa bi se sami povezali na podatkovno bazo, kjer bi uporabili zgenerirano SQL kodo za kreiranje baze. Ker za razvoj uporabljamo Laravel (podpoglavje 2.5), sem uporabil eno izmed storitev, ki jih ponuja - migracije. Migracije so datoteke, s katerimi definiramo shemo podatkovne baze. Vsaka migracijska datoteka predstavlja tabelo v podatkovni bazi. Znotraj migracij se uporablja razred Schema, s pomoˇcjo katerega definiramo tabelo in njene povezave z drugimi tabelami.

Ob migraciji se bo vsaka migracijska datoteka prevedla v SQL stavek ter v podatkovni bazi ustvarila definirano tabelo. Primer migracijske datoteke je predstavljen kasneje v okviru podpoglavja 3.2.2.

3.2.1 Predloge skupin

Ena izmed najbolj pomembnih tabel v podatkovni bazi je tabela skupin (angl.

groups), v kateri hranimo vse skavtske skupine. Skavtske skupine so med se- boj razliˇcne. Ne razlikujejo se samo po imenih, ampak tudi po tipu skupine.

Obstaja veˇc tipov skavtskih skupin, kot so ognjiˇsˇce, steg, veja, vod itd. Vsaka skupina je sestavljena iz imena ter tipa skupine. Na primer skupina z ime- nom Dornberk 1 je tipa steg. Za hranjenje imen in drugih lastnosti skupin

(27)

Diplomska naloga 11 sem ustvaril tabelo ’groups’, za tipe skupin pa tabelo ’group types’. Ta dva podatka sem logiˇcno povezal z uporabo tujega kljuˇca ’group type id’, kot prikazuje slika 3.1. Slika 3.2 pa prikazuje primer podatkov v tabeli ’groups’.

Slika 3.1: Tabeli ’groups’ in ’group types’

V naˇsem primeru pride pri taki shemi do podvajanja podatkov. Skupine, kot so PP, IV, VV, BB ..., so tipa veja in nekatere izmed teh imajo skoraj vsi stegi. To pomeni, da ˇce ima 5 stegov skupino IV, bo v tabeli 5 skupin z istim imenom. Podvajanje podatkov po nepotrebnem zaseda veˇc pomnilniˇskega prostora. Slika 3.2 prikazuje tudi podvajanje imen skupin.

Slika 3.2: Primer podvajanja podatkov v tabeli ’groups’

Ko se ustvarjajo skupine, mora spletni vmesnik vedeti, katere skupine lahko uporabnik ustvari. Na primer, ko se steg na novo ustvari, je v skupini

(28)

samo stegovodja. Ta vloga ima pravico dodajanja vej in drugih skupin. Ker so skavtske veje ˇze definirane, jih mora vmesnik uporabniku ponuditi na iz- biro, da jih uporabnikom ni treba vedno znova ustvariti. Pri taki shemi se lahko zgodi, da ˇse niso ustvarjene vse moˇzne skupine in vmesnik nima nobene skupine, ki jo lahko predlaga, saj nikjer v shemi nimamo shranjenih moˇznih vej in skupin. Za odpravo tega problema in podvajanja podatkov, sem atri- bute ’name’, ’short name’ in ’group type id’ iz tabele ’groups’ premaknil v novo tabelo ’group templates’. Tuji kljuˇc ’group type id’ zdaj kaˇze iz tabele

’group templates’ na tabelo ’group types’. V tabeli ’groups’ pa sem dodal atribut ’group template id’, ki sluˇzi kot tuji kljuˇc in za vsako skupino pove, katera predloga ji pripada. Novo strukturo prikazuje slika 3.3.

Slika 3.3: Del sheme, ki prikazuje implementacijo predlog skupin

Nova tabela bo vsebovala vnaprej definirane skupine, kot so PP, IV ..., ki jih lahko uporabi vsak steg, ne da bi se v bazi podvojile. V tabeli pa bodo tudi druge zasebne skupine, ki jih stegi ustvarijo zase. Atribut ’is core’ raz- likuje predefinirane skupine, ko so dostopne vsem, in zasebne skupine, vidne samo v skupinah, ki jim pripadajo. S tem doseˇzemo tudi funkcionalnost, ki nam omogoˇca, da uporabniku predlagamo ˇze ustvarjene predloge skupin, ki jih lahko uporabi za svojo skupino. Pomembno je omeniti, da atribut ’id’ v

’group templates’ ne predstavlja dejanske skupine v drevesni strukturi, am- pak samo predlogo, na katero kaˇze dejanska skupina. Za to imamo ˇse vedno tabelo ’groups’, ki predstavlja dejanske skupine v drevesni strukturi. Slika 3.4 prikazuje primer podatkov v tabeli ’group templates’.

(29)

Diplomska naloga 13

Slika 3.4: Primer podatkov v tabeli ’group templates’

Na primer, ko ˇzeli stegovodja v stegu Dornberk 1 ustvariti skupino IV, mu bo vmesnik to skupino predlagal - skupaj z drugimi predlogami. Nova skupina bo ustvarjena v tabeli ’groups’ z unikatnim id-jem ter lokacijo v drevesni strukturi. Da se ve, da je to skupina IV, pa poskrbi tuji kljuˇc

’group template id’, ki ima vrednost id-ja predloge skupine IV v tabeli

’group templates’. Na isti naˇcin lahko ustvarijo svojo skupino IV vsi stegi.

Tudi pri taki implementaciji se bodo vrednosti atributa ’group template id’

podvajale. Temu se ne moremo izogniti, ampak v primerjavi s prejˇsnjo im- plementacijo bistveno zmanjˇsamo porabo pomnilniˇskega prostora. Primer podatkov v tabeli ’groups’ prikazuje slika 3.5 v podpoglavju 3.2.2.

3.2.2 Drevesna struktura skupin

Ena izmed pomembnih funkcionalnosti naˇse spletne aplikacije je ustvarjanje skupin znotraj skupin. Za vsako skupino moramo vedeti njene prednike in potomce. Na primer steg Dornberk 1 ima veˇc podskupin in te podskupine imajo tudi svoje podskupine. Primer strukture, ki jo ˇzelimo hraniti v podat- kovni bazi, prikazuje slika 1.1 v podpoglavju Struktura skavtske organizacije (1.1). Za vsako skupino moramo hraniti podatek, ki nam pove njeno lokacijo v drevesni strukturi. Za to funkcionalnost sem uporabil Postgres razˇsiritev ltree. Razˇsiritev doda nov podatkovni tip ltree, ki omogoˇca predstavitev po-

(30)

datkov v drevesni strukturi in efektivno poizvedovanje. Tip ltree je v osnovi niz, ki zdruˇzuje veˇc nizov, loˇcenih s piko (npr. ’1.2.3.4’).

Podatkovno strukturo ltree sem uporabil v tabeli ’groups’, na polju ’path’.

To polje bo za vsako skupino predstavljalo lokacijo v hierarhiji skupin. Migra- cija v programski kodi 3.1 prikazuje tabelo ’groups’, ki predstavlja skupino.

Programska koda 3.1: Migracija za tabelo skupin z uporabo razreda Schema

Schema::create(’groups’, function (Blueprint $table) {

$table->increments(’id’);

$table->string(’path’, 255)->nullable();

$table->foreignId(’group_template_id’) ->constrained(’group_templates’) ->onDelete(’cascade’);

$table->timestamps();

});

$query = ’ALTER TABLE groups

ALTER COLUMN path TYPE "ltree"

USING "path"::"ltree";

CREATE INDEX path_gist_idx ON groups

USING GIST (path);’;

DB::connection()->getPdo()->exec($query);

Znotraj create metode se uporablja spremenljivko $table, razreda Blue- print. Preko te spremenljivke lahko ustvarjamo polja, ki bodo v tabeli.

Vsakemu polju doloˇcimo tudi podatkovni tip. Ker razred Blueprint ne podpira podatkovnega tipa ltree, sem polje ’path’ najprej definiral kot tipa niz. Nato sem dodal dve SQL poizvedbi, ki se bosta izvedli po kreiranju tabele ’groups’. Prva bo spremenila tip polja ’path’ iz niza v ltree. Druga pa bo iz polja ustvarila GiST (Generalized Search Tree) indeks, ki bo omogoˇcil hitrejˇse poizvedovanje po polju ’path’. GiST je razˇsiritev Postgres vmesnika,

(31)

Diplomska naloga 15 ki omogoˇca razvijalcem dodajanje novih podatkovnih tipov, nad katerimi se lahko uporabi indeks. Omogoˇca razˇsiritev funkcionalnosti iskanja po indeksu.

Ltree razˇsiritev vsebuje svojo razˇsiritev indeksa, ki nad tem podatkovnim ti- pom omogoˇca veˇc operacij. Privzeti Postgres indeks teh operacij ne pozna in jih ne zna izvajati [10].

Na sliki 3.5 je prikazan primer podatkov v tabeli ’groups’. Prikazuje vrednosti polja ’path’. To polje je niz, ki ga sestavljajo id-ji skupin, loˇcenih s piko, in pove celotno pot od korena drevesa do skupine. Zadnji id v polju

’path’ pripada skupini. Iz polj ’path’ v tabeli ’groups’ lahko sestavimo drevo.

Slika 3.5: Primer podatkov v tabeli ’groups’

Drevesna predstavitev skupin iz slike 3.5 je prikazana na sliki 3.6. Razˇsiritev ltree ponuja veliko operacij za poizvedovanje po drevesni strukturi. Za naˇso aplikacijo je glavnega pomena poizvedovanje po podskupinah skupin. SQL stavek za poizvedovanje podskupin skupin je prikazan v programski kodi 3.2

Programska koda 3.2: SQL stavek za pridobitev podskupin skupine

SELECT * FROM groups WHERE path ~ ’1.2.*{1}’;

(32)

Slika 3.6: Vizualizacija drevesa, ki ga sestavljajo skupine v tabeli ’groups’

Naˇs zaledni sistem je ogrodje Laravel, preko katerega se poizveduje podat- kovno bazo. Laravel-ov ORM omogoˇca poizvedovanje podatkovne baze z uporabo modelov, kar pomeni, da nam ni treba pisati SQL stavkov. V Laravel-u so tabele predstavljene kot modeli. Model za skupino se imenuje

’Group’. Znotraj modela so definirane funkcije, preko katerih lahko model spreminjamo ali poizvedujemo njegove podatke iz podatkovne baze. Pro- gramska koda 3.3 prikazuje metodo children, ki vrne otroke skupine, nad katero kliˇcemo metodo.

Programska koda 3.3: Metoda za pridobitev podskupin v Laravel modelu skupine

// Group.php

public function children() {

return Group::whereRaw(’path ~ ?’, [$this->path . ’.*{1}’]);

}

(33)

Diplomska naloga 17 V primeru, da bi potrebovali vse potomce neke skupine, bi v model sku- pine dodali metodo descendants, kot prikazuje programska koda 3.4.

Programska koda 3.4: Metoda za pridobitev potomcev v Laravel modelu skupine

// Group.php

public function descendants() {

return Group::whereRaw(’? @> path’, [$this->path]);

}

3.2.3 Vloge in pravice

V opisu strukture skavtske organizacije (podpoglavje 1.1) sem omenil, da ima vsaka skavtska skupina svoje vloge, ki so dodeljene ˇclanom. ˇClan ima lahko po skupinah veˇc vlog. Vloge so dodeljene tipom skupin (tabela ’group types’), predlogam skupin (tabela ’group templates’) ter neposredno na skupino (ta- bela ’groups’). Na primer tip skupine veja ima vloge, kot so voditelj veje, voditelj itd. Predlogna skupina IV, ki je tipa veja, ima ˇse svoje dodatne vloge. Aplikacija bo omogoˇcala tudi vloge po meri, ki bodo vidne samo v skupini, v kateri je bila vloga ustvarjena. Zato bodo vloge vezane tudi na tabelo skupin - ’groups’. Vsaka vloga ima tudi pravice, ki veljajo samo v skupinah, ki jim je vloga dodeljena.

Za hranjenje vseh vlog sem ustvaril tabelo ’roles’, za pravice pa tabelo

’permissions’. Najprej sem implementiral vloge in pravice za tipe skupin. Ker so vloge po tipih skupin ˇze vnaprej definirane, sem ustvaril vmesno tabelo

’group type roles’, ki povezuje tipe skupin z njihovimi vlogami. Vsebuje dva tuja kljuˇca. Kljuˇc ’group type id’, ki je povezan s primarnim kljuˇcem tabele

’group types’ ter kljuˇc ’role id’, ki je povezan s primarnim kljuˇcem tabele

’roles’. To omogoˇca, da za vsak tip skupine lahko doloˇcimo niˇc ali veˇc vlog.

Tuja kljuˇca sta tudi skupni edinstven (angl. unique) kljuˇc, ki prepreˇci, da bi tip skupine imel dve isti vlogi. Del sheme prikazuje slika 3.7.

(34)

Slika 3.7: Del sheme, ki prikazuje implementacijo povezovanja vlog s tipi skupin

S tem doseˇzemo, da ima vsak tip skupine vloge, ki mu pripadajo in bodo na spletnem vmesniku prikazane kot vloge, ki so na voljo uporabnikom.

Ker ima vsaka vloga v tipu skupine tudi svoje pravice, sem ustvaril tabelo

’role permission group type’, ki povezuje vloge v tipu skupine s pravicami.

Slika 3.8 prikazuje dopolnjeno shemo iz slike 3.7. S to strukturo poskrbimo, Slika 3.8: Dopolnjena shema, ki za vsako vlogo v tipu skupine hrani pravice

da so v tabeli ’role permission group type’ lahko samo pravice za vloge, ki obstajajo v tipu skupine. Na primer, ˇce tipu skupine steg dodamo vlogo ste- govodja, lahko tej vlogi v tem tipu skupine doloˇcimo pravice. V primeru, da vloga stegovodja ni dodeljena v tip skupine steg, tej vlogi ne moremo doloˇciti pravic, saj ne obstaja v tabeli ’group type roles’. Isti princip se uporabi tudi pri vlogah in pravicah predlognih skupin v tabeli ’group templates’.

(35)

Diplomska naloga 19 Ce ˇˇ zelimo uporabnikom omogoˇciti, da lahko ustvarjajo svoje vloge in jim tudi doloˇcijo pravice, moramo uporabiti isti princip tudi za tabelo ’groups’.

S tem pristopom lahko zasebne vloge poveˇzemo s skupino, v kateri so bile ustvarjene. Slika 3.9 prikazuje implementacijo za zasebne vloge po skupinah.

Slika 3.9: Shema, ki omogoˇca zasebne vloge v skupinah

Ko uporabnik ustvari zasebno vlogo, se v tabeli ’roles’ nastavi atribut

’is public’ na false, kar pomeni, da je vloga zasebna in je spletni vmesnik ne bo dobil skupaj z javnimi vlogami. Slika 3.10 prikazuje zdruˇzen del sheme za vloge in pravice.

(36)

Slika 3.10: Zdruˇzena shema vlog in pravic skupin

(37)

Diplomska naloga 21 Uporabnikove skupine, vloge in pravice

Ce ˇˇ zelimo povezati uporabnike s skupinami, moramo med tabelo ’users’, ki hrani vse uporabnike, in tabelo ’groups’, ki hrani skupine, dodati vmesno ta- belo. To vmesno tabelo sem poimenoval ’memberships’. Slika 3.11 prikazuje implementacijo. Za hranjenje uporabnikovih vlog v vsaki skupini, pa sem do-

Slika 3.11: Povezovanje uporabnikov s skupinami preko vmesne tabele

’memberships’

dal vmesno tabelo ’membership roles’, ki vsako uporabnikovo ˇclanstvo poveˇze z vlogo. Aplikacija omogoˇca tudi, da lahko ˇclanu doloˇcimo dodatne pravice, ki jih njegove vloge nimajo. Ta dodatna pravica bo vezana na ˇclanstvo upo- rabnika in ne na njegove vloge. Za hrambo teh pravic bo poskrbela tabela

’membership permissions’. Slika 3.12 prikazuje implementacijo uporabniko- vih vlog in pravic po skupinah.

(38)

Slika 3.12: Vloge in pravice uporabnikovih ˇclanstev

3.3 Zaledni sistem

Zaledni sistem je uporabnikom neviden, je pa za aplikacijo kljuˇcnega pomena.

Zaledni sistem poskrbi za avtentikacijo, avtorizacijo, obdelavo in shranjeva- nje podatkov, omejevanje dostopa do podatkov, povezavo na podatkovno bazo ipd. Naˇs zaledni sistem je implementiran kot aplikacijski programski vmesnik (API). To je vmesnik za namensko programiranje oziroma aplikacij- ski programski vmesnik. API doloˇca operacije (rutine), ki jih zaledni sistem podpira, ter vhodne podatke, ki so potrebni za izvedbo te operacije. Toˇcno doloˇceni so tudi izhodni podatki. API je neodvisen od implementacije spre- dnjega dela aplikacije, saj ga lahko za pridobivanje podatkov kliˇce kdorkoli.

Okoli teh podatkov pa lahko implementiramo npr. Android aplikacijo, iOS

(39)

Diplomska naloga 23 aplikacijo, spletno aplikacijo, aplikacijo za pametno uro, namizno aplikacijo ipd. Za izdelavo zalednega sistema sem uporabil ogrodje Laravel (podpo- glavje 2.5). V tem podpoglavju je opisanih nekaj primerov operacij ali rutin, ki jih naˇs API zaledni sistem podpira za delovanje naˇse spletne aplikacije.

3.3.1 Avtentikacija

Avtentikacija ali preverjanje pristnosti je proces, s katerim se zaledni sistem prepriˇca, da je uporabnik zares tisti uporabnik, za katerega se predstavlja.

Vzemimo za primer API za vreme. Uporabnik poˇslje zahtevo z imenom kraja kot vhodni podatek in API mu kot izhodni podatek vrne vreme za izbrani kraj. V tem primeru se uporabniku ni potrebno avtenticirat, saj API-ju ni pomembno, kdo je zahteval podatke o vremenu. Podatki, ki jih tak API ponuja, niso vezani na uporabnika. So sploˇsni in poleg tega tudi prosto dosto- pni. V naˇsem primeru skavt pripada raznim skupinam znotraj organizacije, ima svoje uporabniˇsko ime, dogodke, ki se jih bo udeleˇzil, profilno sliko itd.

Naˇs zaledni sistem mora vedeti, kdo je uporabnik, ki zahteva podatke, sicer ne ve, kateri podatki mu pripadajo. V naˇsi aplikaciji se bo za avtentikacijo uporabljalo uporabniˇsko ime in geslo.

Laravel ima paket imenovan Sanctum. Ta paket razˇsiri Laravel aplikacijo z avtentikacijskim sistemom za SPA. Ker je naˇs uporabniˇski vmesnik SPA, je ta paket logiˇcna izbira. Po namestitvi in konfiguraciji paketa moramo definirati operacijo, ki bo kot vhodni podatek prejela uporabniˇsko ime in geslo. Prvi korak je definiranje url poti, na katero bo uporabniˇski vmesnik poslal zahtevo za prijavo. Laravel ima v ta namen datoteko api.php, kjer so definirane vse vstopne poti v API. Vsaka zahteva se mora zaˇceti z besedo

’api’ (npr. api/auth/login). Laravel bo ’api’ besedo odstranil in kar ostane iskal v datotekiapi.php. Primer takega zapisa je prikazan v programski kodi 3.5.

(40)

Programska koda 3.5: Definirana vstopna pot za prijavo

// Api.php

Route::post(’auth/login’, [AuthController::class, ’login’]);

Ta pot nam pove, da API sprejme POST HTTP zahtevo na url

api/auth/login. AuthControllerje ime kontrolerja, ki bo prevzel nadaljnjo izvedbo zahteve, login pa je metoda znotraj kontrolerja, ki se bo izvedla in obdelala podane podatke. Da bo ta pot delovala, moramo ustvariti kontro- ler AuthController in znotraj definirati metodo login, kot je prikazano v programski kodi 3.6

Programska koda 3.6: Metoda login

// AuthController.php

public function login(LoginRequest $request) {

$credentials = $request->validated();

if (Auth::attempt($credentials)) {

return new UserResource(Auth::user());

}

return response()->json(

[’error’ => ’Invalid login credentials.’], 401 );

}

Metoda dobi kot parameter spremenljivko $request. Ta spremenljivka vse- buje vse podatke zahteve, ki jih vmesnik poˇslje. Spremenljivka $request je tipa LoginRequest. Ko Laravel pokliˇce metodo, naredi instanco razreda LoginRequest, kjer smo definirali validacijska pravila (programska koda 3.7) za prejete podatke.

(41)

Diplomska naloga 25 Programska koda 3.7: Validacija prejetih podatkov zahteve za prijavo

// LoginRequest.php public function rules() {

return [

’username’: ’required|string’,

’password’: ’required|string’

];

}

Metoda rules vrne polje, v katerem doloˇcimo podatke, ki jih priˇcakujemo za prijavno zahtevo. V naˇsem primeru smo doloˇcili, da sta uporabniˇsko ime in geslo obvezna in sta tipa string. V primeru, da eden izmed podatkov krˇsi kakˇsno izmed pravil, bo Laravel avtomatsko vrnil odgovor, v katerem bodo razlogi neuspeˇsne validacije podatkov (programska koda 3.8). Laravel omogoˇca, da lahko tudi sami sestavimo odgovore na neuspeˇsne validacije vhodnih podatkov.

Programska koda 3.8: Primer odgovora po meri za neuspeˇsno validacijo

// LoginRequest.php

public function messages() {

return [

’username.required’ => ’Uporabnisko ime je obvezno.’,

’password.required’ => ’Geslo je obvezno.’, ];

}

Po validaciji podatkov se zaˇcne izvajanje metode login (programska koda 3.6). V spremenljivko $credentials shranimo podatke, ki so bili validirani - v naˇsem primeru uporabniˇsko ime in geslo. V if stavku preverimo, ˇce lahko uporabnika prijavimo. Ce je uporabniˇsko ime ali geslo napaˇˇ cno, vrnemo JSON odgovor s statusno kodo 401. V primeru, da je prijava uspeˇsna, vrnemo uporabnikove podatke.

(42)

3.3.2 Sistem povabil

Naˇso spletno aplikacijo bodo lahko uporabljali le skavti. To pomeni, da bo za registracijo potrebno povabilo od nekoga, ki je ˇze registriran in ima za to dovoljenje. V datotekiapi.phpje definirana skupina poti, za katere mora biti uporabnik avtenticiran in je prikazana v programski kodi 3.9. Za preverjanje statusa avtentikacije poskrbi paket Sanctum.

Programska koda 3.9: Pot, ki zdruˇzuje poti, za katere je potrebna avtentika- cija

// api.php

Route::group([’middleware’ => ’auth:sanctum’], function() { // Definirane poti

}

Uporabnik, ki hoˇce nekoga povabiti, se mora najprej avtenticirat z zahtevo za prijavo. Po uspeˇsni avtentikaciji lahko naredi zahtevo za ustvarjanje povabila.

Pot za ustvarjanje povabila je prikazana v programski kodi 3.10.

Programska koda 3.10: Pot za ustvarjanje povabila

// api.php

Route::group([’middleware’ => ’auth:sanctum’], function() { // ...

Route::post(

’auth/invitation’, [InvitationController::class, ’store’]

);

// ...

}

Ta pot nam pove, da bo za ustvarjanje povabila poskrbela metoda store v razreduInvitationController, ki je definiran v datotekiInvitationControl- ler.php. Metoda je prikazana v programski kodi 3.11

(43)

Diplomska naloga 27 Programska koda 3.11: Metoda, ki ustvari povabilo

// InvitationController.php

public function store(CreateInvitationRequest $request) {

$invitationData = $request->validated();

$invitationData[’invited_by’] = Auth::id();

$invitation = new Invitation($invitationData);

$invitation->generateInvitationToken();

$invitation->save();

Mail::to($invitation->email)

->send(new InvitationMail($invitation, Auth::user()));

return response()->json([’success’ => true], 200);

}

Metoda kot parameter dobi spremenljivko $request, ki smo ji doloˇcili tip razreda CreateInvitationRequest. Ko se metoda zaˇcne izvajati, Lara- vel samodejno ustvari instanco razreda CreateInvitationRequest, kate- remu poda kot vhodni parameter spremenljivko $request. Tam se preveri, ˇce ima uporabnik pravico ustvarjanja povabila (programska koda 3.12) ter izvede validacijo prejetih podatkov. Po uspeˇsni avtorizaciji in validaciji po- datkov, ustvarimo spremenljivko$invitationData, kateri dodelimo validirane podatke. Dodamo ji tudi podatek, kdo je povabilo ustvaril, zgeneriramo nakljuˇcen niz ter ustvarimo novo instanco povabila. Na koncu se poˇslje e- sporoˇcilo na naslov, ki je bil v vhodnih podatkih. E-sporoˇcilo vsebuje spletno povezavo do registracijske strani, kjer se lahko novi uporabnik registrira.

(44)

Programska koda 3.12: Avtorizacija zahteve za ustvarjanje povabila

// CreateInvitationRequest.php public function authorize() {

$permission = ’invite-new-user’;

$user = Auth::user();

$groupId = intval($this[’groupId’]);

$isInGroup = $user->memberships() ->where(’user_id’, $user->id) ->where(’group_id’, $groupId) ->exists();

if (!$isInGroup) { return false;

}

$group = Group::withoutRelationships()->find($groupId);

$groupTypeId = $group->template->type->id;

$permissionId = DB::table(’permissions’) ->where(’slug’, $permission) ->select(’id’)

->get()

->first()->id;

$roleIds = RolePermissionGroupType::select(’role_id’) ->where(’permission_id’, $permissionId)

->where(’group_type_id’, $groupTypeId) ->get();

return $user->roleIds()->whereIn(’role_id’, $roleIds)->exists();

}

Metoda authorize odloˇci, ali je uporabnik, ki je poslal zahtevo, avtorizi- ran za izvedbo zahteve. V primeru, da vrne false, bo Laravel vrnil HTTP odgovor s kodo 403, kar pomeni, da ni avtoriziran. ˇCe vrne true, se bo izve- dla validacija v metodi rules. V naˇsem primeru metoda naprej preveri, ali

(45)

Diplomska naloga 29 je uporabnik, ki je poslal zahtevo za povabilo novega uporabnika v njegovo skupino, tudi sam ˇclan te skupine. ˇCe ni, bo metoda vrnila false. To je prikazano v programski kodi 3.13.

Programska koda 3.13: Preveri, ˇce je uporabnik vˇclanjen v skupino

// CreateInvitationRequest.php ...

$isInGroup = $user->memberships() ->where(’user_id’, $user->id) ->where(’group_id’, $groupId) ->exists();

if (!$isInGroup) { return false;

} ...

Po tem v$group shranimo model skupine, ki jo pridobimo iz baze, in v$gro- upTypeId, shranimo id tipa te skupine. $permissionId je id pravice, za katero preverjamo, ali jo uporabnik ima. Id pridobimo s klicem v bazo. $roleIds je polje id-jev vlog, ki imajo pravico, ki jo iˇsˇcemo, v tipu skupine, v katero ˇzelimo dodati novega uporabnika. Na koncu vrnemo rezultat (true/false) preverbe, ˇce ima prijavljen uporabnik katero izmed teh vlog, kar kaˇze pro- gramska koda 3.14. Po uspeˇsni avtorizaciji se izvede ˇse validacija prejetih podatkov za ustvarjanje povabila, prikazana v programski kodi 3.15.

(46)

Programska koda 3.14: Preveri uporabnikivo vlogo v skupini

// CreateInvitationRequest.php ...

$group = Group::withoutRelationships()->find($groupId);

$groupTypeId = $group->template->type->id;

$permissionId = DB::table(’permissions’) ->where(’slug’, $permission) ->select(’id’)

->get()

->first()->id;

$roleIds = RolePermissionGroupType::select(’role_id’) ->where(’permission_id’, $permissionId)

->where(’group_type_id’, $groupTypeId) ->get();

return $user->roleIds()->whereIn(’role_id’, $roleIds)->exists();

Programska koda 3.15: Validacija prejetih podatkov za ustvarjanje povabila

// CreateInvitationRequest.php public function rules()

{

return [

’email’ => ’required|email|unique:invitations’,

’group_id’ => ’required|exists:groups,id’, ];

}

Pri tej validaciji smo dodali tudi pravilo ’unique:invitations’, ki pravi, da mora biti elektronski naslov unikaten v tabeli povabil. ˇCe elektronski naslov v tabeli povabil ˇze obstaja, pomeni, da je bil uporabnik s tem naslovom ˇze povabljen. Drugo novo pravilo, ’exists:groups,id’, pa je definirano za id skupine, v katero ˇzelimo povabiti novega ˇclana. Doloˇca, da mora skupina s tem id-jem v bazi obstajati. Ko prejemnik klikne na povezavo znotraj e- sporoˇcila, ga preusmeri (programska koda 3.16) na naˇs uporabniˇski vmesnik,

(47)

Diplomska naloga 31 kjer mu pokaˇze registracijsko formo.

Programska koda 3.16: Url preusmeritve na uporabniˇski vmesnik

localhost:4200/register?invitation_token=13acd03eab755632738a08aec699226d

Ko uporabnik izpolni formo in klikne na gumb ”Registracija”, se skupaj z uporabnikovimi podatki poˇslje tudi ˇzeton, ki ga vmesnik pridobi iz url-ja.

API najprej validira podatke, kjer preveri, ali ˇzeton obstaja. Programska koda 3.17 prikazuje pot za registracijo, 3.18 pa metodo za validacijo podatkov za registracijo.

Programska koda 3.17: API pot za registracijo

// api.php

Route::post(’auth/register’, [UserController::class, ’store’]);

Programska koda 3.18: Validacija podatkov za registracijo

// RegistrationRequest.php public function rules() {

return [

’firstName’ => ’required|string’,

’lastName’ => ’required|string’,

’scoutName’ => ’nullable|string’,

’invitation_token’ => ’required|string|exists:invitations’,

’password’ => ’required|string’, // ...

];

}

Ce ˇˇ zeton obstaja, se nadaljuje izvajanje metode store (programska koda 3.19) v UserController.php, kjer se najprej preveri, ˇce je ˇzeton ˇze bil upora- bljen. Po tem se ustvari uporabnika s prejetimi podatki ter sproˇzi dogodek (angl. event) tipa UserRegisteredEvent. Kot parametre tega dogodka podamo model novega uporabnika ter id skupine, v katero je bil povabljen.

(48)

Programska koda 3.19: Ustvarjanje novega uporabnika

// UserController.php

public function store(RegistrationRequest $request) {

$regData = $request->validated();

$invitation = Invitation::where(

’invitation_token’, ’=’, $regData->invitation_token )->get();

if ($invitation->registered_at) {

return response()->json(’This token is no longer valid’, 422);

}

$fullName = $regData->firstName . ’ ’ . $regData->lastName;

$group = Group::find($invitation->group_id);

$defaultGroup = $group->stegId();

$user = new User;

$user->name = $fullName;

$user->default_group = $defaultGroup;

$user->email = $invitation->email;

$user->password = $regData->password;

$user->save();

event(new UserRegisteredEvent($user, $invitation->group_id));

return response()->json([’success’ => $user], 200);

}

Ko sproˇzimo dogodek, se odzove posluˇsalec (angl. listener), ki pridobi po- datke dogodka in uporabnika doda v skupine, ki jim pripada (programska koda 3.20). Doda ga v skupino, v katero je bil povabljen, in v vse njene prednike.

(49)

Diplomska naloga 33 Programska koda 3.20: Dodajanje novega uporabnika v skupine

// AddRegisteredUserToGroup.php

public function handle(UserRegisteredEvent $event) {

$group_id = $event->group_id;

$user = $event->user;

$user_id = $user->id;

$groupAncestorsArray = explode(’.’, Group::find($group_id)->path);

$user->groups()->attach($groupAncestorsArray);

}

Nov uporabnik je uspeˇsno ustvarjen.

3.3.3 Komunikacija in obveˇ sˇ canje

Ena izmed glavnih lastnosti naˇse aplikacije je obveˇsˇcanje in komunikacija med ˇclani. Za hitro komunikacijo poskrbi realnoˇcasovni klepet. Obveˇsˇcanje deluje znotraj spletne aplikacije, v sklopu obvestil v realnem ˇcasu ter z uporabo elektronske poˇste.

Pogovor in obveˇsˇcanje v realnem ˇcasu

Ko se v spletnih aplikacijah omenja realen ˇcas, je v ozadju komunikacijski protokol WebSocket 2.7. Za naˇso implementacijo sem se odloˇcil za ponu- dnika Pusher, ki ponuja WebSocket streˇznike kot storitev. Naˇs vmesnik bo vzpostavil povezavo z njihovimi WebSocket streˇzniki, preko katerih bo preje- mal podatke. Podatke bo najprej naˇsa Laravel aplikacija poslala na Pusher streˇznik, od koder bodo preko WebSocket povezave poslani na naˇs spletni uporabniˇski vmesnik.

Laravel aplikacijo je treba najprej konfigurirati, da ve, kako in kam poˇsiljati podatke. Z uporabo composer paketa, specifiˇcno narejenega za Pusher sto- ritev, bo naˇsa aplikacija znala poˇsiljati podatke na njihov streˇznik. Ko se prijavimo na Pusher storitve preko njihovega spletnega vmesnika, nam zge- nerirajo nekaj kljuˇcev, s katerimi se bo Laravel aplikacija avtenticirala pri

(50)

poˇsiljanju podatkov. Po namestitvi in konfiguraciji, je aplikacija pripravljena za uporabo WebSocket storitev.

Ogrodje Laravel ima v datoteki channels.php definirane oddajne kanale (programska koda 3.21). Pri definiranju kanalov doloˇcimo predlogo za ime ter avtorizacijsko metodo. Avtorizacija se bo izvedla, ko bo uporabniˇski vmesnik poslal zahtevo po posluˇsanju kanala. Pri oddajanju na kanalih pa doloˇcimo, kateri podatki se bodo oddajali ter ali je kanal javen (angl. public) ali zaseben (angl. private). Na te kanale se bo naroˇcil naˇs spletni vmesnik, preko katerih bo prejemal podatke v realnem ˇcasu. V naˇsem primeru bo vsak prijavljen uporabnik imel svoj zasebni kanal. Ime kanala bo user.<uporabnikov id>

(npr. user.10 za uporabnika z id-jem 10).

Programska koda 3.21: Definiran kanal za uporabnike

// channels.php

Broadcast::channel(’user.{userId}’, function ($user, $userId) { return (int) $user->id === (int) $userId;

});

Uporabniki bodo lahko v skupinah komunicirali v skupinskih pogovorih. Ko je uporabnik avtenticiran, vmesnik naredi GET zahtevo na /api/message- s/group/{id}, s katero pridobi vsa dosedanja skupinska sporoˇcila za doloˇceno skupino. Za poˇsiljanje sporoˇcila pa se uporabi POST zahteva na/api/messa- ges/group, s katero se poˇslje vsebina sporoˇcila in id skupine, v katero ˇzelimo poslati sporoˇcilo. Za obe zahtevi se tudi preveri, ˇce je uporabnik vˇclanjen v skupino, za katero zahteva ali poˇsilja sporoˇcila. Programska koda 3.22 prikazuje poti za sporoˇcila, 3.23 pa kodo za ustvarjanje sporoˇcila.

(51)

Diplomska naloga 35 Programska koda 3.22: Poti za sporoˇcila

// api.php

Route::group([’prefix’ => ’messages’], function() { Route::get(

’/group/{id}’, [GroupMessageController::class, ’index’]

);

Route::post(

’/group’, [GroupMessageController::class, ’store’]

);

});

Programska koda 3.23: Ustvarjanje sporoˇcila

// GroupMessageController.php

public function store(GroupMessageRequest $request) {

$message = $request->validated();

$groupMessage = GroupMessage::create([

’message’ => $message[’message’],

’group_id’ => $message[’groupId’],

’user_id’ => Auth::id() ]);

broadcast(new NewMessage($groupMessage))->toOthers();

...

}

Ko se sporoˇcilo ustvari, se pokliˇce globalna metoda broadcast, v katero kot parameter podamo instanco razreda NewMessage, ki definira naˇcin oddajanja sporoˇcila. Kot parameter mu podamo ustvarjeno sporoˇcilo.

V razreduNewMessage, prikazanem v programski kodi 3.24, definiramo metodo broadcastOn, ki vrne imena kanalov, na katerih se bo na novo ustvarjeno sporoˇcilo oddajalo. Ker vsak uporabnik posluˇsa svoj kanal, bomo oddajali na vseh kanalih uporabnikov, ki so ˇclani skupine, v kateri je bilo sporoˇcilo ustvarjeno.

(52)

Programska koda 3.24: Doloˇcanje, na katerih kanalih oddajamo

// NewMessage.php public $message;

public function __construct($message) {

$this->message = $message;

}

public function broadcastOn() {

$groupId = $this->message->group_id;

$userId = $this->message->user_id;

$userIds = Membership::select(’user_id’) ->where(’group_id’, $groupId) ->where(’user_id’, ’<>’, $userId) ->get()

->pluck(’user_id’);

return $userIds->map(function($id){

return new PrivateChannel(’user.’ . (int) $id);

})->toArray();

}

V razredu doloˇcimo spremenljivke, ki jih bo Laravel poslal storitvi Pusher in bodo preko WebSocket povezave poslani uporabniku na spletni vmesnik.

Pri poˇsiljanju bodo upoˇstevane samo javne spremenljivke. V tem primeru bomo oddajali sporoˇcilo, zato je spremenljivka $message javna. Vrednost ji doloˇcimo v konstruktorju razreda, ko naredimo novo instanco. To se zgodi, ko pokliˇcemobroadcast metodo vGroupMessageController (programska koda 3.23) z novo instanco razreda NewMessage. S poizvedbo na podatkovno bazo, iz tabele ’memberships’ dobimo vse id-je uporabnikov, ki so v skupini, v katero je bilo poslano sporoˇcilo. Polje id-jev shranimo v spremenljivko

$userIds. Nazadnje, polje id-jev preslikamo v polje instanc zasebnih kanalov, ki jim kot parameter podamo imena kanalov. Ime kanala dobimo tako, da zdruˇzimo niz ’user.’ z id-jem uporabnika (npr. user.12, user.2, itd.). To so imena kanalov, na katerih se bo oddajalo novo sporoˇcilo. Vsako oddajanje lahko tudi poimenujemo (programska koda 3.25). To nam omogoˇca, da na

(53)

Diplomska naloga 37 vmesniku filtriramo prejete podatke.

Programska koda 3.25: Imenovanje oddajanja novih sporoˇcil

// NewMessage.php

public function broadcastAs() { return ’message.created’;

}

Na isti naˇcin tudi obveˇsˇcamo ˇclane o novi objavi, novem dogodku ipd. Kako uporabniˇski vmesnik te podatke prejme in prikaˇze, bomo spoznali v poglavju Uporabniˇski vmesnik (podpoglavje 3.4.3).

Poˇsiljanje e-sporoˇcil

Za obveˇsˇcanje uporabnikov, ki trenutno niso prijavljeni v spletno aplika- cijo, bomo uporabili e-sporoˇcila. Laravel ponuja tudi reˇsitev za poˇsiljanje e- sporoˇcil. Za ponudnika e-sporoˇcil bomo za zaˇcetek uporabili storitev Gmail, ki je brezplaˇcna. Ustvaril sem nov Gmail raˇcun ter v konfiguracijski datoteki Laravela izpolnil konfiguracijska polja za e-sporoˇcila, kar prikazuje program- ska koda 3.26.

Programska koda 3.26: Primer konfiguracije za poˇsiljanje e-sporoˇcil preko storitve Gmail

// .env

MAIL_MAILER=smtp

MAIL_HOST=smtp.googlemail.com MAIL_PORT=465

MAIL_USERNAME=janez.novak@gmail.com MAIL_PASSWORD=janez1234

MAIL_ENCRYPTION=ssl

MAIL_FROM_ADDRESS=janez.novak@gmail.com MAIL_FROM_NAME="${APP_NAME}"

Ko imamo vsa konfiguracijska polja izpolnjena, lahko zaˇcnemo s poˇsiljanjem e-sporoˇcil. Kot primer lahko vzamemo poˇsiljanje e-sporoˇcila povabljenemu uporabniku (programska koda 3.11, 3.27). Ko se ˇzeton za povabilo ustvari,

(54)

se uporabi Laravel-ov razred Mail za poˇsiljanje e-sporoˇcil.

Programska koda 3.27: Primer poˇsiljanja e-sporoˇcila za povabilo uporabnika

Mail::to($invitation->email)->send(

new InvitationMail($invitation, Auth::user()) );

Kot parameter v statiˇcno metodo to podamo elektronski naslov, na kate- rega ˇzelimo poslati naˇse obvestilo ter doloˇcimo, kateri razred, ki predstavlja e-sporoˇcilo, se uporabi pri poˇsiljanju. Razred InvitationMail je namenjen specifiˇcno za poˇsiljanje e-sporoˇcil za povabila novih uporabnikov. Kot pa- rameter sprejme model povabila ter model prijavljenega uporabnika, ki je ustvaril povabilo. Naloga razreda je, da po potrebi podatke obdela ter jih preda pogledu (angl. view), kjer doloˇcimo izgled naˇsega e-sporoˇcila, kar je prikazano v programski kodi 3.28. Za to uporabimo strukturni jezik HTML.

Primer takega razreda prikazuje programska koda 3.29

Programska koda 3.28: Doloˇcitev predloge za izgled e-sporoˇcila

public function build() {

return $this->view(’emails.InvitationMail’);

}

InvitationMail razred razˇsiri Laravel-ov razred Mailable in prepiˇse nje- govo metodo build. V metodi doloˇcimo, kateri pogled se bo uporabil za e-sporoˇcilo. ’emails.InvitationMail’ pove, da ta pogled spada v kategorijo

’emails’ in se imenuje ’InvitationMail’. Laravel ve, da mora ta pogled poi- skati v mapi views/emails.

(55)

Diplomska naloga 39 Programska koda 3.29: Predloga za izgled e-sporoˇcila

<!-- InvitationMail.blade.php -->

<!DOCTYPE html>

<html lang="en">

<head><!-- ... --></head>

<body>

<h1>Pozdravljen skavt!</h1>

<p> Uporabnik {{ $user->name }} te je povabil v ScoutBook, spletni aplikaciji namenjeni samo za skavte. </p>

<p>Klikni

<a

href="http://localhost:4201/register?invitation_token={{

$invitationLink }}">

tukaj

</a>

da se registriras.

</p>

</body>

</html>

3.4 Uporabniˇ ski vmesnik

Uporabniˇski vmesnik je vmesnik med uporabnikom in naˇso celotno arhitek- turo. Z uporabo vmesnika uporabniku predstavimo, poenostavimo in po- enotimo vse funkcionalnosti, ki jih omogoˇca naˇs zaledni sistem. Izgled in uporabnikova izkuˇsnja vmesnika sta zelo pomembna, saj prispevata k zado- voljstvu uporabnikov in s tem uspeˇsnosti aplikacije. Spletni vmesniki v osnovi temeljijo na treh tehnologijah - HTML (podpoglavje 2.1), CSS (podpoglavje 2.2) in JavaScript (podpoglavje 2.3). Z uporabo HTML-ja naredimo struk- turo strani, s CSS-om grafiˇcno podobo in z JavaScript-om dodamo strani dodatno funkcionalnost. Loˇcimo dve vrsti spletnih strani - statiˇcne in di- namiˇcne. Te dve vrsti nista strogo loˇceni, obstajajo tudi hibridne variante.

Statiˇcne so tiste, za katere nam streˇznik vrne HTML datoteko z vso vsebino, kar pomeni, da hrani HTML datoteko za vsako njihovo stran. Pri dinamiˇcnih

(56)

ima veˇcjo vlogo JavaScript, preko katerega pridobijo podatke in upravljajo z vsebino. Pod dinamiˇcne spletne strani spadajo tudi tako imenovane eno- stranske aplikacije (SPA). Za SPA je znaˇcilno, da iz streˇznika pridobi samo JavaScript kodo, ki nam z zahtevami na zaledni sistem pridobi podatke, s katerimi ustvari HTML vsebino. Take spletne strani imenujemo spletne apli- kacije, saj so bolj interaktivne.

Za izdelavo naˇse spletne aplikacije smo uporabili ogrodje Angular (pod- poglavje 2.4).

3.4.1 Lokalno stanje aplikacije

Ce ˇˇ zelimo doseˇci maksimalno odzivnost spletne aplikacije, je treba hraniti stanje podatkov. S tem se izognemo ponovnemu klicu podatkov na zaledni sistem. Na primer, ko naˇsa aplikacija naredi zahtevo na zaledni sistem za pridobitev skupin, v katerih je prijavljen uporabnik, si prejete podatke shrani v stanje. Naslednjiˇc, ko si bo uporabnik ˇzelel pogledati svoje skupine, se bodo pokazale takoj, saj jih je aplikacija shranila v svoje stanje in ni treba narediti ˇse ene zahteve na zaledje.

Implementirati je treba sistem, ki bo upravljal stanje - urejanje, doda- janje in brisanje. ˇCe nimamo dobrega sistema za upravljanje stanja in se ˇstevilo podatkov, ki jih aplikacija hrani, poveˇca, postane upravljanje stanja zelo kompleksno in zahtevno. Za to obstajajo tudi razne knjiˇznice, ki imple- mentirajo tak sistem in nam prihranijo ˇcas. V naˇsem primeru nismo uporabili knjiˇznice, saj je trenutno stanje, ki ga mora naˇsa aplikacija hraniti, relativno majhno. Zato sem se odloˇcil za svojo implementacijo. Slika 3.13 prikazuje konˇcno arhitekturo aplikacije. Jedro se uporablja za pridobivanje podatkov iz zalednega sistema in hranjenje podatkov v stanju. Za pridobivanje po- datkov se uporabljajo asinhrone storitve (angl. services). Jedro upravljajo tako imenovane aplikacijske fasade. Fasade so del arhitekture, ki z uporabo storitev pridobijo podatke in jih shranijo v aplikacijsko stanje. Uporabljajo se tudi za morebitno obdelavo podatkov. Komponente uporabljajo fasade za poizvedovanje podatkov, ki jih prikaˇzejo uporabnikom, ter za shranjevanje

(57)

Diplomska naloga 41

Slika 3.13: Arhitektura spletne aplikacije

podatkov, ki jih uporabnik vnese. Po potrebi tudi zdruˇzujejo podatke veˇc fasad. Na sliki 3.14 je prikazan primer pretoka podatkov znotraj aplikacijske arhitekture. Fasade, stanja in asinhrone storitve so imenovani po podatkih, ki jih obdelujejo/hranijo/pridobivajo. Asinhrone storitve vsebujejo samo kodo, potrebno za komuniciranje z zalednim sistemom. Storitve stanja so zadolˇzene za shranjevanje, posodabljanje ter brisanje podatkov iz stanja. Fasade znajo komunicirati s stanji in asinhronimi storitvami. Sluˇzijo kot vmesnik, ki ga komponente uporabijo za komuniciranje s stanji in asinhronimi storitvami.

Komponenta group.component.ts predstavlja skavtsko skupino. Vsaka skupina, ki jo dobimo z zalednega sistema, ima tudi polje id-jev uporabni- kov, ki pripadajo tej skupini. Ko ˇzeli komponenta prikazati uporabnike, ki so v skupini, pokliˇce metodo vusers.facade.tsin ji kot parameter poda polje id- jev uporabnikov. ˇCe ˇclanov skupine ni v stanju users.state.ts, user.facade.ts uporabi metodo v users.service.ts. Polje id-jev, ki jih je dobilo iz kompo- nente, uporabi kot parameter metode v user.service.ts, ki vrne uporabnike z zalednega sistema. Fasada groups.facade.ts shrani nove uporabnike v stanje in jih vrne komponenti group.component.ts, ki uporabnike prikaˇze. Nasle-

(58)

Slika 3.14: Pretok podatkov

dnjiˇc, ko bo komponenta group.component.ts zahtevala uporabnike skupine, ne bo treba narediti zahteve na zaledni sistem, saj bodo shranjeni v stanju.

3.4.2 Preverjanje uporabnikovih pravic

Tudi na spletnem vmesniku je potrebno preverjanje uporabnikovih dovo- ljenj, saj na podlagi tega vemo, kaj lahko uporabniku prikaˇzemo. Na primer, samo uporabnik s pravico ’invite-new-user’ lahko vidi gumb za dodajanje novega ˇclana v steg. Za implementacijo preverjanja sem uporabil direktive (angl. directives), ki jih Angular ponuja. Direktivo se uporabi kot atribut na HTML elementu, s katero lahko element spreminjamo, skrijemo, prikaˇzemo ipd. Ustvaril sem direktivo z imenom ifCan, ki vsebuje metodo checkPer- mission. ˇCe ima uporabnik zahtevano pravico, se HTML element s pripa- dajoˇco vsebino prikaˇze, v nasprotnem primeru se skrije. Programska koda 3.30 prikazuje primer uporabe te direktive.

Reference

POVEZANI DOKUMENTI

Protokola IPv4 in IPv6 sta na ˇ zalost nezdruˇ zljiva, zato potrebujemo mehanizme, ki omogoˇ cijo prenos podatkov tako preko omreˇ zja IPv4 kot tudi preko omreˇ zja IPv6 in ki

ˇ Ce ˇ zelimo namesto matrike P iz prejˇsnje toˇ cke ortogonalno matriko Q, moramo samo ˇse normirati lastne vektorje, matrika D pa lahko ostane nespremenjena.. Vektor #– x 0

Pred zaˇ cetkom dela na projektu pa moramo uporabnikom aplikacije ˇse doloˇ citi uporabniˇske vloge na tem projektu (Skrbnik metodologije, Produktni vodja ali ˇ Clan razvojne

To virtualizacijo lahko prav tako kot virtualizacijo strojne opreme izva- jamo doma na osebnem raˇ cunalniku.. ˇ Ce pa ˇ zelimo, lahko navidezni raˇ cunalnik najamemo pri enem

Poleg stila, ki ga moramo izbrati, preden zaˇ cnemo z realizacijo, moramo doloˇ citi tudi, koliko podrobnosti oziroma toˇ cnosti bomo vkljuˇ cili v ˇ ziˇ cne okvirje (angl.

Ce se ˇ ˇ zelimo prepriˇ cati, da je ekstrem, ki smo ga poiskali, res minimum, pogledamo predznak drugega odvoda hitrosti po ˇ casu... Kolikˇsen je kotni pospeˇsek

Ce ˇ ˇ zelimo pin uporabiti kot izhod moramo poleg zgoraj omenjenih regi- strov nastaviti ˇse registra, ki doloˇ cata naˇ cin izhoda ter hitrost osveˇ zevanja.. Hitrost osveˇ

Doloˇ citi moramo tudi ali se izvorni oziroma ciljni naslov med prenosom poveˇ cujeta (angl.. ˇ Ce poˇsiljamo podatke iz polja ali podatke sprejemamo v polje je namreˇ c