Login/logout, Firestore rules, readme
This commit is contained in:
parent
9ae5c9e9a6
commit
b3291391ff
8 changed files with 116 additions and 51 deletions
45
README.md
45
README.md
|
@ -1,27 +1,36 @@
|
||||||
# Szakdolgozat
|
# Szakdolgozat
|
||||||
|
Egy webalkalmazás, amely nyomonköveti egy-egy kurzus követelményeinek teljesitését oktatók és hallgatók számára.
|
||||||
|
|
||||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.0.2.
|
## Szerepkörök
|
||||||
|
Csak bejelentkezett felhasználók férhetnek hozzá bármilyen adathoz. A saját adataikat mindig tudják módositani.
|
||||||
|
|
||||||
## Development server
|
### Admin
|
||||||
|
* Teljes jogosultsága van az adatokhoz, kivéve a felhasználók adatait
|
||||||
|
* Hozzá tud rendelni más felhasználókat szerepkörökhöz egy-egy kurzus kapcsán
|
||||||
|
|
||||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
### Hallgató
|
||||||
|
* Az adott kurzushoz tartozó adatokat csak megtekinteni tudja
|
||||||
|
|
||||||
## Code scaffolding
|
### Oktató
|
||||||
|
* Az adott kurzushoz tartozó összes adatot tudja módositani, kivéve a nevet, azonositót.
|
||||||
|
|
||||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
## Adatok
|
||||||
|
### Kurzus
|
||||||
|
* Azonositó
|
||||||
|
* Név
|
||||||
|
* Leirás
|
||||||
|
* Követelmények
|
||||||
|
* Eredmények
|
||||||
|
* Oktatók
|
||||||
|
* Hallgatók
|
||||||
|
|
||||||
## Build
|
### Követelmény
|
||||||
|
* ...
|
||||||
|
|
||||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
|
### Eredmény
|
||||||
|
* ...
|
||||||
|
|
||||||
## Running unit tests
|
### Felhasználó
|
||||||
|
* Azonositó
|
||||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
* E-mail, jelszó (külön tárolva)
|
||||||
|
* Admin-e
|
||||||
## Running end-to-end tests
|
|
||||||
|
|
||||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
|
||||||
|
|
||||||
## Further help
|
|
||||||
|
|
||||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
|
||||||
|
|
|
@ -1,9 +1,24 @@
|
||||||
rules_version = '2';
|
rules_version = '2';
|
||||||
service cloud.firestore {
|
service cloud.firestore {
|
||||||
match /databases/{database}/documents {
|
match /databases/{database}/documents {
|
||||||
match /{document=**} {
|
function sameUser(user) {
|
||||||
allow read, write: if
|
return request.auth != null && request.auth.uid == user;
|
||||||
request.time < timestamp.date(2021, 1, 10);
|
}
|
||||||
|
function getUserData() {
|
||||||
|
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
|
||||||
|
}
|
||||||
|
//Felhasználói adatok kezelése
|
||||||
|
match /users/{user} {
|
||||||
|
allow create: if sameUser(user) && request.auth.uid == request.resource.data.author_uid;
|
||||||
|
allow get, list, update, delete: if sameUser(user) && request.auth.uid == resource.data.author_uid;
|
||||||
|
}
|
||||||
|
//Adminoknak mindent lehet
|
||||||
|
match /data/{document=**} {
|
||||||
|
allow get, list, create, update, delete: if getUserData().isAdmin == true;
|
||||||
|
}
|
||||||
|
//Diákok megnézhetik a kurzus adatait
|
||||||
|
match /data/courses/{course} {
|
||||||
|
allow get, list: if request.auth.uid in resource.data.students;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<mat-toolbar color="primary">
|
<mat-toolbar color="primary">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
aria-label="Toggle sidenav"
|
aria-label="Oldalsáv"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="drawer.toggle()"
|
(click)="drawer.toggle()"
|
||||||
*ngIf="isHandset$ | async">
|
*ngIf="isHandset$ | async">
|
||||||
|
@ -22,11 +22,16 @@
|
||||||
</button>
|
</button>
|
||||||
<span>Szakdolgozat</span>
|
<span>Szakdolgozat</span>
|
||||||
<span class="toolbar-spacer"></span>
|
<span class="toolbar-spacer"></span>
|
||||||
<a mat-button routerLink="/register">Regisztráció</a>
|
<span *ngIf="loginService.loggedInUser">
|
||||||
<a mat-button routerLink="/login">
|
<a mat-button (click)="logout()">Kijelentkezés</a>
|
||||||
Bejelentkezés
|
</span>
|
||||||
<mat-icon aria-hidden="false" aria-label="Bejelentkezés">login</mat-icon>
|
<span *ngIf="!loginService.loggedInUser">
|
||||||
</a>
|
<a mat-button routerLink="/register">Regisztráció</a>
|
||||||
|
<a mat-button routerLink="/login">
|
||||||
|
Bejelentkezés
|
||||||
|
<mat-icon aria-hidden="false" aria-label="Bejelentkezés">login</mat-icon>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
<div style="margin: 20px">
|
<div style="margin: 20px">
|
||||||
<!-- <mat-slider min="1" max="100" step="1" value="1"></mat-slider> -->
|
<!-- <mat-slider min="1" max="100" step="1" value="1"></mat-slider> -->
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
import { Component } from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout';
|
||||||
import { Observable } from 'rxjs';
|
import {Observable} from 'rxjs';
|
||||||
import { map, shareReplay } from 'rxjs/operators';
|
import {map, shareReplay} from 'rxjs/operators';
|
||||||
|
import {LoginService} from './shared/login.service';
|
||||||
import firebase from 'firebase';
|
import firebase from 'firebase';
|
||||||
|
import {Router} from '@angular/router';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrls: ['./app.component.css']
|
styleUrls: ['./app.component.css']
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent implements OnInit {
|
||||||
|
|
||||||
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
|
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
|
||||||
.pipe(
|
.pipe(
|
||||||
|
@ -17,13 +19,15 @@ export class AppComponent {
|
||||||
shareReplay()
|
shareReplay()
|
||||||
);
|
);
|
||||||
|
|
||||||
constructor(private breakpointObserver: BreakpointObserver) {}
|
constructor(private breakpointObserver: BreakpointObserver, public loginService: LoginService,
|
||||||
|
private router: Router) {
|
||||||
}
|
|
||||||
|
|
||||||
firebase.initializeApp((window as any).firebaseCredentials);
|
|
||||||
firebase.auth().onAuthStateChanged(user => {
|
|
||||||
if (user) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
async logout(): Promise<void> {
|
||||||
|
await this.loginService.logout();
|
||||||
|
await this.router.navigate(['/']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Email</mat-label>
|
<mat-label>Email</mat-label>
|
||||||
<input matInput class="mat-input-element" type="email" name="email" required="required"
|
<input matInput class="mat-input-element" type="email" name="email" required="required"
|
||||||
placeholder="h123456@stud.u-szeged.hu"/>
|
placeholder="h123456@stud.u-szeged.hu" [(ngModel)]="email"/>
|
||||||
<mat-hint>Egyetemi email cim</mat-hint>
|
<mat-hint>Egyetemi email cim</mat-hint>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Jelszó</mat-label>
|
<mat-label>Jelszó</mat-label>
|
||||||
<input matInput class="mat-input-element" type="password" name="password" required="required"
|
<input matInput class="mat-input-element" type="password" name="password" required="required"
|
||||||
minlength="8"/>
|
minlength="8" [(ngModel)]="pass"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<button mat-raised-button color="primary" (click)="doLogin()">Bejelentkezés</button>
|
<button mat-raised-button color="primary" (click)="doLogin()">Bejelentkezés</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
|
import {Router} from '@angular/router';
|
||||||
|
import {LoginService} from '../shared/login.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-login',
|
selector: 'app-login',
|
||||||
|
@ -6,10 +8,18 @@ import {Component, OnInit} from '@angular/core';
|
||||||
styleUrls: ['./login.component.css']
|
styleUrls: ['./login.component.css']
|
||||||
})
|
})
|
||||||
export class LoginComponent implements OnInit {
|
export class LoginComponent implements OnInit {
|
||||||
|
email: string;
|
||||||
|
pass: string;
|
||||||
|
|
||||||
|
constructor(private router: Router, private loginService: LoginService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
doLogin(): void {
|
async doLogin(): Promise<void> {
|
||||||
|
await this.loginService.login(this.email, this.pass);
|
||||||
|
await this.router.navigate(['/']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ import {Component, OnInit} from '@angular/core';
|
||||||
import {ErrorStateMatcher} from '@angular/material/core';
|
import {ErrorStateMatcher} from '@angular/material/core';
|
||||||
import {AbstractControl, FormControl, FormGroupDirective, NgForm, ValidationErrors, Validators} from '@angular/forms';
|
import {AbstractControl, FormControl, FormGroupDirective, NgForm, ValidationErrors, Validators} from '@angular/forms';
|
||||||
import firebase from 'firebase';
|
import firebase from 'firebase';
|
||||||
|
import {LoginService} from '../shared/login.service';
|
||||||
|
import {Router} from '@angular/router';
|
||||||
|
|
||||||
export class FormErrorStateMatcher implements ErrorStateMatcher {
|
export class FormErrorStateMatcher implements ErrorStateMatcher {
|
||||||
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
|
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
|
||||||
|
@ -17,7 +19,7 @@ export class FormErrorStateMatcher implements ErrorStateMatcher {
|
||||||
})
|
})
|
||||||
export class RegisterComponent implements OnInit {
|
export class RegisterComponent implements OnInit {
|
||||||
|
|
||||||
constructor() {
|
constructor(private loginService: LoginService, private router: Router) {
|
||||||
}
|
}
|
||||||
|
|
||||||
emailFormControl = new FormControl('', [
|
emailFormControl = new FormControl('', [
|
||||||
|
@ -73,8 +75,8 @@ export class RegisterComponent implements OnInit {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const user = await firebase.auth().createUserWithEmailAndPassword(this.emailFormControl.value, this.passFormControl.value);
|
await this.loginService.createUser(this.emailFormControl.value, this.passFormControl.value);
|
||||||
alert('User created: ' + user);
|
await this.router.navigate(['/']);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e);
|
alert(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,29 @@
|
||||||
import { Injectable } from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
|
import firebase from 'firebase';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class LoginService {
|
export class LoginService {
|
||||||
|
|
||||||
constructor() { }
|
loggedInUser: firebase.User;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
firebase.initializeApp((window as any).firebaseCredentials);
|
||||||
|
firebase.auth().onAuthStateChanged(user => {
|
||||||
|
this.loggedInUser = user;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async createUser(email: string, pass: string): Promise<void> {
|
||||||
|
const user = await firebase.auth().createUserWithEmailAndPassword(email, pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
async logout(): Promise<void> {
|
||||||
|
await firebase.auth().signOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
async login(email: string, pass: string): Promise<void> {
|
||||||
|
await firebase.auth().signInWithEmailAndPassword(email, pass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue