Finished the wizard #865 (For Plex Anyway)

pull/1389/head
tidusjar 8 years ago
parent fa0e167650
commit 7294f942d9

@ -0,0 +1,34 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: OmbiClaims.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
namespace Ombi.Core.Claims
{
public static class OmbiClaims
{
public const string Admin = nameof(Admin);
}
}

@ -51,6 +51,8 @@ namespace Ombi.Core.IdentityResolver
public async Task<bool> CredentialsValid(string username, string password)
{
var user = await UserRepository.GetUser(username);
if (user == null) return false;
var hash = HashPassword(password, user.Salt);
return hash.HashedPass.Equals(user.Password);

@ -1,8 +1,13 @@
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Ombi.Core.Claims;
using Ombi.Core.IdentityResolver;
using Ombi.Core.Models;
using Ombi.Models;
namespace Ombi.Controllers
{
@ -21,6 +26,37 @@ namespace Ombi.Controllers
{
return await IdentityManager.GetUser(this.HttpContext.User.Identity.Name);
}
/// <summary>
/// This is what the Wizard will call when creating the user for the very first time.
/// This should never be called after this.
/// The reason why we return false if users exists is that this method doesn't have any
/// authorization and could be called from anywhere.
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
[HttpPost("Wizard")]
[AllowAnonymous]
public async Task<bool> CreateWizardUser([FromBody] UserAuthModel user)
{
var users = await IdentityManager.GetUsers();
if (users.Any())
{
// No one should be calling this. Only the wizard
return false;
}
await IdentityManager.CreateUser(new UserDto
{
Username = user.Username,
UserType = UserType.LocalUser,
Claims = new List<Claim>() {new Claim(ClaimTypes.Role, OmbiClaims.Admin)},
Password = user.Password,
});
return true;
}
}
}

@ -0,0 +1,65 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: StatusController.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models;
namespace Ombi.Controllers
{
public class StatusController : BaseV1ApiController
{
public StatusController(ISettingsService<OmbiSettings> ombi)
{
Ombi = ombi;
}
private ISettingsService<OmbiSettings> Ombi { get; }
[AllowAnonymous]
[HttpGet]
public HttpStatusCode GetStatus()
{
return HttpStatusCode.OK;
}
[AllowAnonymous]
[HttpGet("Wizard")]
public async Task<object> WizardStatus()
{
var settings = await Ombi.GetSettingsAsync();
return new { Result = settings?.Wizard ?? false};
}
}
}

@ -20,6 +20,20 @@
<Content Include="wwwroot\app\auth\IUserLogin.ts" />
<Content Include="wwwroot\app\login\login.component.html" />
<Content Include="wwwroot\app\login\login.component.ts" />
<Content Include="wwwroot\app\services\identity - Copy.service.js">
<DependentUpon>identity - Copy.service.ts</DependentUpon>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="wwwroot\app\services\identity - Copy.service.js.map">
<DependentUpon>identity - Copy.service.js</DependentUpon>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="wwwroot\app\services\identity - Copy.service.ts">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="wwwroot\app\services\identity.service.js" />
<Content Include="wwwroot\app\services\identity.service.js.map" />
<Content Include="wwwroot\app\services\identity.service.ts" />
<Content Include="wwwroot\app\services\plex.service.js" />
<Content Include="wwwroot\app\services\plex.service.js.map" />
<Content Include="wwwroot\app\services\plex.service.ts">
@ -28,6 +42,10 @@
<Content Include="wwwroot\app\services\settings.service.js" />
<Content Include="wwwroot\app\services\settings.service.js.map" />
<Content Include="wwwroot\app\services\settings.service.ts" />
<Content Include="wwwroot\app\services\status.service.js" />
<Content Include="wwwroot\app\services\status.service.js.map" />
<Content Include="wwwroot\app\services\status.service.ts" />
<Content Include="wwwroot\app\services\useridentity.service.ts" />
<Content Include="wwwroot\app\settings\emby\emby.component.html" />
<Content Include="wwwroot\app\settings\emby\emby.component.js" />
<Content Include="wwwroot\app\settings\emby\emby.component.js.map" />
@ -59,11 +77,6 @@
<Content Include="wwwroot\app\wizard\createadmin\createadmin.component.js" />
<Content Include="wwwroot\app\wizard\createadmin\createadmin.component.js.map" />
<Content Include="wwwroot\app\wizard\createadmin\createadmin.component.ts" />
<Content Include="wwwroot\app\wizard\createadmin\plex.component.js">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="wwwroot\app\wizard\createadmin\plex.component.js.map" />
<Content Include="wwwroot\app\wizard\createadmin\plex.component.ts" />
<Content Include="wwwroot\app\wizard\mediaserver\mediaserver.component.html">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>

@ -1,6 +1,6 @@
<p-growl [value]="notificationService.messages" [life]="500000"></p-growl>
<nav class="navbar navbar-default navbar-fixed-top">
<nav *ngIf="showNav" class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">

@ -9,5 +9,13 @@ import { AuthService } from './auth/auth.service';
})
export class AppComponent {
constructor(public notificationService: NotificationService, public authService : AuthService) { };
constructor(public notificationService: NotificationService, public authService: AuthService) {
this.showNav = true;
//console.log(this.route);
//if (this.route.("/Wizard/*") !== -1) {
// this.showNav = false;
//}
}
showNav :boolean;
}

@ -23,6 +23,9 @@ import { SettingsService } from './services/settings.service';
import { AuthService } from './auth/auth.service';
import { AuthGuard } from './auth/auth.guard';
import { AuthModule } from './auth/auth.module';
import { IdentityService } from './services/identity.service';
import { StatusService } from './services/status.service';
// Modules
import { SettingsModule } from './settings/settings.module';
@ -69,7 +72,9 @@ const routes: Routes = [
NotificationService,
AuthService,
AuthGuard,
SettingsService
SettingsService,
IdentityService,
StatusService
],
bootstrap: [AppComponent]
})

@ -1,8 +1,8 @@
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../auth/auth.service';
import { StatusService } from '../services/status.service';
import { NotificationService } from '../services/notification.service';
@Component({
@ -11,7 +11,13 @@ import { NotificationService } from '../services/notification.service';
templateUrl: './login.component.html',
})
export class LoginComponent {
constructor(private authService: AuthService, private router: Router, private notify: NotificationService) { }
constructor(private authService: AuthService, private router: Router, private notify: NotificationService, private status: StatusService) {
this.status.getWizardStatus().subscribe(x => {
if (!x.result) {
this.router.navigate(['Wizard']);
}
});
}
username: string;

@ -0,0 +1,17 @@
import { Injectable } from '@angular/core';
import { AuthHttp } from 'angular2-jwt';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { ServiceAuthHelpers } from './service.helpers';
@Injectable()
export class IdentityService extends ServiceAuthHelpers {
constructor(http: AuthHttp, private regularHttp : Http) {
super(http, '/api/v1/Identity/');
}
createUser(username:string,password:string): Observable<boolean> {
return this.regularHttp.post(`${this.url}/Wizard/`, JSON.stringify({username:username, password:password}), { headers: this.headers }).map(this.extractData);
}
}

@ -0,0 +1,16 @@
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { ServiceHelpers } from './service.helpers';
@Injectable()
export class StatusService extends ServiceHelpers {
constructor(http : Http) {
super(http, '/api/v1/status/');
}
getWizardStatus(): Observable<any> {
return this.http.get(`${this.url}/Wizard/`, { headers: this.headers }).map(this.extractData);
}
}

@ -1,23 +1,47 @@
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { IdentityService } from '../../services/identity.service';
import { SettingsService } from '../../services/settings.service';
import { AuthService } from '../../auth/auth.service';
import { NotificationService } from '../../services/notification.service';
@Component({
selector: 'ombi',
moduleId: module.id,
templateUrl: './plex.component.html',
templateUrl: './createadmin.component.html',
})
export class PlexComponent {
export class CreateAdminComponent {
constructor(private identityService: IdentityService, private notificationService: NotificationService,
private router: Router, private auth: AuthService, private settings: SettingsService) { }
constructor(private authService: AuthService, private notificationService: NotificationService) { }
username: string;
password: string;
createUser() {
this.identityService.createUser(this.username, this.password).subscribe(x => {
if (x) {
// Log me in.
this.auth.login({ username: this.username, password: this.password }).subscribe(c => {
localStorage.setItem("id_token", c.access_token);
// Mark that we have done the settings now
this.settings.getOmbi().subscribe(ombi => {
ombi.wizard = true;
this.settings.saveOmbi(ombi).subscribe();
this.router.navigate(['search']);
});
});
} else {
this.notificationService.error("Error in creating user",
"There was an error... You might want to put this on Github...");
}
});
}
}

@ -6,13 +6,16 @@ import { RouterModule, Routes } from '@angular/router';
import { WelcomeComponent } from './welcome/welcome.component';
import { MediaServerComponent } from './mediaserver/mediaserver.component';
import { PlexComponent } from './plex/plex.component';
import { CreateAdminComponent } from './createadmin/createadmin.component';
import { PlexService } from '../services/plex.service';
import { IdentityService } from '../services/identity.service';
const routes: Routes = [
{ path: 'Wizard', component: WelcomeComponent},
{ path: 'Wizard/MediaServer', component: MediaServerComponent},
{ path: 'Wizard/Plex', component: PlexComponent},
{ path: 'Wizard/CreateAdmin', component: CreateAdminComponent},
];
@NgModule({
@ -24,13 +27,15 @@ const routes: Routes = [
declarations: [
WelcomeComponent,
MediaServerComponent,
PlexComponent
PlexComponent,
CreateAdminComponent
],
exports: [
RouterModule
],
providers: [
PlexService
PlexService,
IdentityService
],
})

Loading…
Cancel
Save