mirror of https://github.com/Squidex/squidex.git
88 changed files with 933 additions and 590 deletions
@ -0,0 +1,96 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.IO; |
||||
|
using System.Security.Cryptography; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Assets |
||||
|
{ |
||||
|
public sealed class HasherStream : Stream |
||||
|
{ |
||||
|
private readonly Stream inner; |
||||
|
private readonly IncrementalHash hasher; |
||||
|
|
||||
|
public override bool CanRead |
||||
|
{ |
||||
|
get { return inner.CanRead; } |
||||
|
} |
||||
|
|
||||
|
public override bool CanSeek |
||||
|
{ |
||||
|
get { return false; } |
||||
|
} |
||||
|
|
||||
|
public override bool CanWrite |
||||
|
{ |
||||
|
get { return false; } |
||||
|
} |
||||
|
|
||||
|
public override long Length |
||||
|
{ |
||||
|
get { return inner.Length; } |
||||
|
} |
||||
|
|
||||
|
public override long Position |
||||
|
{ |
||||
|
get { return inner.Position; } |
||||
|
set { throw new NotSupportedException(); } |
||||
|
} |
||||
|
|
||||
|
public HasherStream(Stream inner, HashAlgorithmName hashAlgorithmName) |
||||
|
{ |
||||
|
Guard.NotNull(inner, nameof(inner)); |
||||
|
|
||||
|
this.inner = inner; |
||||
|
|
||||
|
hasher = IncrementalHash.CreateHash(hashAlgorithmName); |
||||
|
} |
||||
|
|
||||
|
public override int Read(byte[] buffer, int offset, int count) |
||||
|
{ |
||||
|
var read = inner.Read(buffer, offset, count); |
||||
|
|
||||
|
if (read > 0) |
||||
|
{ |
||||
|
hasher.AppendData(buffer, offset, read); |
||||
|
} |
||||
|
|
||||
|
return read; |
||||
|
} |
||||
|
|
||||
|
public byte[] GetHashAndReset() |
||||
|
{ |
||||
|
return hasher.GetHashAndReset(); |
||||
|
} |
||||
|
|
||||
|
public string GetHashStringAndReset() |
||||
|
{ |
||||
|
return Convert.ToBase64String(GetHashAndReset()); |
||||
|
} |
||||
|
|
||||
|
public override void Flush() |
||||
|
{ |
||||
|
throw new NotSupportedException(); |
||||
|
} |
||||
|
|
||||
|
public override long Seek(long offset, SeekOrigin origin) |
||||
|
{ |
||||
|
throw new NotSupportedException(); |
||||
|
} |
||||
|
|
||||
|
public override void SetLength(long value) |
||||
|
{ |
||||
|
throw new NotSupportedException(); |
||||
|
} |
||||
|
|
||||
|
public override void Write(byte[] buffer, int offset, int count) |
||||
|
{ |
||||
|
throw new NotSupportedException(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; |
||||
|
|
||||
|
import { Form, ValidatorsEx } from '@app/shared'; |
||||
|
|
||||
|
import { UserDto } from './../services/users.service'; |
||||
|
|
||||
|
export class UserForm extends Form<FormGroup> { |
||||
|
constructor( |
||||
|
formBuilder: FormBuilder |
||||
|
) { |
||||
|
super(formBuilder.group({ |
||||
|
email: ['', |
||||
|
[ |
||||
|
Validators.email, |
||||
|
Validators.required, |
||||
|
Validators.maxLength(100) |
||||
|
] |
||||
|
], |
||||
|
displayName: ['', |
||||
|
[ |
||||
|
Validators.required, |
||||
|
Validators.maxLength(100) |
||||
|
] |
||||
|
], |
||||
|
password: ['', |
||||
|
[ |
||||
|
Validators.nullValidator |
||||
|
] |
||||
|
], |
||||
|
passwordConfirm: ['', |
||||
|
[ |
||||
|
ValidatorsEx.match('password', 'Passwords must be the same.') |
||||
|
] |
||||
|
], |
||||
|
permissions: [''] |
||||
|
})); |
||||
|
} |
||||
|
|
||||
|
public load(user?: UserDto) { |
||||
|
if (user) { |
||||
|
this.form.controls['password'].setValidators(null); |
||||
|
|
||||
|
super.load({ ...user, permissions: user.permissions.join('\n') }); |
||||
|
} else { |
||||
|
this.form.controls['password'].setValidators(Validators.required); |
||||
|
|
||||
|
super.load(undefined); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public submit() { |
||||
|
const result = super.submit(); |
||||
|
|
||||
|
if (result) { |
||||
|
result['permissions'] = result['permissions'].split('\n').filter((x: any) => !!x); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.IO; |
||||
|
using System.Security.Cryptography; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Assets |
||||
|
{ |
||||
|
public class HasherStreamTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Should_calculate_hash_while_copying() |
||||
|
{ |
||||
|
var source = GenerateTestData(); |
||||
|
var sourceHash = source.Sha256Base64(); |
||||
|
|
||||
|
var sourceStream = new HasherStream(new MemoryStream(source), HashAlgorithmName.SHA256); |
||||
|
|
||||
|
using (sourceStream) |
||||
|
{ |
||||
|
var target = new MemoryStream(); |
||||
|
|
||||
|
sourceStream.CopyTo(target); |
||||
|
|
||||
|
var targetHash = sourceStream.GetHashStringAndReset(); |
||||
|
|
||||
|
Assert.Equal(sourceHash, targetHash); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private byte[] GenerateTestData(int length = 1000) |
||||
|
{ |
||||
|
var random = new Random(); |
||||
|
var result = new byte[length]; |
||||
|
|
||||
|
random.NextBytes(result); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue