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