Webmaster profile : Check and Solve

I think some the important aspects of software administrator and developer are the capacity to Check and Solve.

To Check rapresent the capacity to be continuos update, himself and the system.

To Solve rapresent the capacity to understand the direction to keep for work out a task.

Exists several possibilities to solve a problem, but few permit you a more long time for checking. To solve means pospone as far as possible the next check.

Use SSL certificate free for 3 months

Create your key (mail.saic.key) and your request (mail.saic.csr):

openssl req -new -newkey rsa:4096 -nodes -subj ‘/CN=mail.saic.it/O=SAIC, Inc./C=IT/ST=Italy/L=Viadana’ -keyout mail.saic.key -out mail.saic.csr

Go to this website and follow the istruction for have back the certificate for your Common Name (mail.saic.it) and the authority certificate :

Certificate Authority https://www.sslforfree.com

I configured my dns.

I set all file permission

chmod 444 mail.saic.*

then vim /etc/postfix/main.cf

smtp_tls_key_file                         = /etc/ssl/certs/mail.saic.key

smtp_tls_cert_file                        = /etc/ssl/certs/mail.saic.crt

smtp_tls_CAfile                           = /etc/ssl/certs/saic.sslforfree.ca

here the console for renew the certificate

great!!

 

It can be useful to check a certificate and key before applying them to your server. The following commands help verify the certificate, key, and CSR (Certificate Signing Request).

Check a certificate

Check a certificate and return information about it (signing authority, expiration date, etc.):

openssl x509 -in server.crt -text -noout

Check a key

Check the SSL key and verify the consistency:

openssl rsa -in server.key -check

Check a CSR

Verify the CSR and print CSR data filled in when generating the CSR:

openssl req -text -noout -verify -in server.csr

Verify a certificate and key matches

These two commands print out md5 checksums of the certificate and key; the checksums can be compared to verify that the certificate and key match.

openssl x509 -noout -modulus -in server.crt| openssl md5
openssl rsa -noout -modulus -in server.key| openssl md5

 

Self Signed Certificate : Commands

Create a private key

openssl genrsa -out server.key 4096

Generate a new private key and certificate signing request

openssl req -out server.csr -new -newkey rsa:4096 -nodes -keyout server.key

Generate a self-signed certificate

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:4096 -keyout server.key -out server.crt

Generate a certificate signing request (CSR) for an existing private key

openssl req -out server.csr -key server.key -new

Generate a certificate signing request based on an existing certificate

openssl x509 -x509toreq -in server.crt -out server.csr -signkey server.key

Remove a passphrase from a private key

openssl rsa -in server.pem -out newserver.pem

Parse a list of revoked serial numbers

openssl crl -inform DER -text -noout -in list.crl

Check a certificate signing request (CSR)

openssl req -text -noout -verify -in server.csr

Check a private key

openssl rsa -in server.key -check

Check a public key

openssl rsa -inform PEM -pubin -in pub.key -text -noout
openssl pkey -inform PEM -pubin -in pub.key -text -noout

Check a certificate

openssl x509 -in server.crt -text -noout
openssl x509 -in server.cer -text -noout

Check a PKCS#12 file (.pfx or .p12)

openssl pkcs12 -info -in server.p12

Verify a private key matches an certificate

openssl x509 -noout -modulus -in server.crt | openssl md5
openssl rsa -noout -modulus -in server.key | openssl md5
openssl req -noout -modulus -in server.csr | openssl md5

Display all certificates including intermediates

openssl s_client -connect www.paypal.com:443

Convert a DER file (.crt .cer .der) to PEM

openssl x509 -inform der -in server.cer -out server.pem

Convert a PEM file to DER

openssl x509 -outform der -in server.pem -out server.der

Convert a PKCS#12 file (.pfx .p12) containing a private key and certificates to PEM

openssl pkcs12 -in server.pfx -out server.pem -nodes

Convert a PEM certificate file and a private key to PKCS#12 (.pfx .p12)

openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -certfile CACert.crt

Apache vs Nginx: Practical Considerations

Introduction

Apache and Nginx are the two most common open source web servers in the world. Together, they are responsible for serving over 50% of traffic on the internet. Both solutions are capable of handling diverse workloads and working with other software to provide a complete web stack.

While Apache and Nginx share many qualities, they should not be thought of as entirely interchangeable. Each excels in its own way and it is important to understand the situations where you may need to reevaluate your web server of choice. This article will be devoted to a discussion of how each server stacks up in various areas.

General Overview

Before we dive into the differences between Apache and Nginx, let’s take a quick look at the background of these two projects and their general characteristics.

Apache

The Apache HTTP Server was created by Robert McCool in 1995 and has been developed under the direction of the Apache Software Foundation since 1999. Since the HTTP web server is the foundation’s original project and is by far their most popular piece of software, it is often referred to simply as “Apache”.

The Apache web server has been the most popular server on the internet since 1996. Because of this popularity, Apache benefits from great documentation and integrated support from other software projects.

Apache is often chosen by administrators for its flexibility, power, and widespread support. It is extensible through a dynamically loadable module system and can process a large number of interpreted languages without connecting out to separate software.

Nginx

In 2002, Igor Sysoev began work on Nginx as an answer to the C10K problem, which was a challenge for web servers to begin handling ten thousand concurrent connections as a requirement for the modern web. The initial public release was made in 2004, meeting this goal by relying on an asynchronous, events-driven architecture.

Nginx has grown in popularity since its release due to its light-weight resource utilization and its ability to scale easily on minimal hardware. Nginx excels at serving static content quickly and is designed to pass dynamic requests off to other software that is better suited for those purposes.

Nginx is often selected by administrators for its resource efficiency and responsiveness under load. Advocates welcome Nginx’s focus on core web server and proxy features.

Connection Handling Architecture

One big difference between Apache and Nginx is the actual way that they handle connections and traffic. This provides perhaps the most significant difference in the way that they respond to different traffic conditions.

Apache

Apache provides a variety of multi-processing modules (Apache calls these MPMs) that dictate how client requests are handled. Basically, this allows administrators to swap out its connection handling architecture easily. These are:

  • mpm_prefork: This processing module spawns processes with a single thread each to handle request. Each child can handle a single connection at a time. As long as the number of requests is fewer than the number of processes, this MPM is very fast. However, performance degrades quickly after the requests surpass the number of processes, so this is not a good choice in many scenarios. Each process has a significant impact on RAM consumption, so this MPM is difficult to scale effectively. This may still be a good choice though if used in conjunction with other components that are not built with threads in mind. For instance, PHP is not thread-safe, so this MPM is recommended as the only safe way of working with mod_php, the Apache module for processing these files.
  • mpm_worker: This module spawns processes that can each manage multiple threads. Each of these threads can handle a single connection. Threads are much more efficient than processes, which means that this MPM scales better than the prefork MPM. Since there are more threads than processes, this also means that new connections can immediately take a free thread instead of having to wait for a free process.
  • mpm_event: This module is similar to the worker module in most situations, but is optimized to handle keep-alive connections. When using the worker MPM, a connection will hold a thread regardless of whether a request is actively being made for as long as the connection is kept alive. The event MPM handles keep alive connections by setting aside dedicated threads for handling keep alive connections and passing active requests off to other threads. This keeps the module from getting bogged down by keep-alive requests, allowing for faster execution. This was marked stable with the release of Apache 2.4.

As you can see, Apache provides a flexible architecture for choosing different connection and request handling algorithms. The choices provided are mainly a function of the server’s evolution and the increasing need for concurrency as the internet landscape has changed.

Nginx

Nginx came onto the scene after Apache, with more awareness of the concurrency problems that would face sites at scale. Leveraging this knowledge, Nginx was designed from the ground up to use an asynchronous, non-blocking, event-driven connection handling algorithm.

Nginx spawns worker processes, each of which can handle thousands of connections. The worker processes accomplish this by implementing a fast looping mechanism that continuously checks for and processes events. Decoupling actual work from connections allows each worker to concern itself with a connection only when a new event has been triggered.

Each of the connections handled by the worker are placed within the event loop where they exist with other connections. Within the loop, events are processed asynchronously, allowing work to be handled in a non-blocking manner. When the connection closes, it is removed from the loop.

This style of connection processing allows Nginx to scale incredibly far with limited resources. Since the server is single-threaded and processes are not spawned to handle each new connection, the memory and CPU usage tends to stay relatively consistent, even at times of heavy load.

Static vs Dynamic Content

In terms of real world use-cases, one of the most common comparisons between Apache and Nginx is the way in which each server handles requests for static and dynamic content.

Apache

Apache servers can handle static content using its conventional file-based methods. The performance of these operations is mainly a function of the MPM methods described above.

Apache can also process dynamic content by embedding a processor of the language in question into each of its worker instances. This allows it to execute dynamic content within the web server itself without having to rely on external components. These dynamic processors can be enabled through the use of dynamically loadable modules.

Apache’s ability to handle dynamic content internally means that configuration of dynamic processing tends to be simpler. Communication does not need to be coordinated with an additional piece of software and modules can easily be swapped out if the content requirements change.

Nginx

Nginx does not have any ability to process dynamic content natively. To handle PHP and other requests for dynamic content, Nginx must pass to an external processor for execution and wait for the rendered content to be sent back. The results can then be relayed to the client.

For administrators, this means that communication must be configured between Nginx and the processor over one of the protocols Nginx knows how to speak (http, FastCGI, SCGI, uWSGI, memcache). This can complicate things slightly, especially when trying to anticipate the number of connections to allow, as an additional connection will be used for each call to the processor.

However, this method has some advantages as well. Since the dynamic interpreter is not embedded in the worker process, its overhead will only be present for dynamic content. Static content can be served in a straight-forward manner and the interpreter will only be contacted when needed. Apache can also function in this manner, but doing so removes the benefits in the previous section.

Distributed vs Centralized Configuration

For administrators, one of the most readily apparent differences between these two pieces of software is whether directory-level configuration is permitted within the content directories.

Apache

Apache includes an option to allow additional configuration on a per-directory basis by inspecting and interpreting directives in hidden files within the content directories themselves. These files are known as .htaccess files.

Since these files reside within the content directories themselves, when handling a request, Apache checks each component of the path to the requested file for an .htaccess file and applies the directives found within. This effectively allows decentralized configuration of the web server, which is often used for implementing URL rewrites, access restrictions, authorization and authentication, even caching policies.

While the above examples can all be configured in the main Apache configuration file, .htaccess files have some important advantages. First, since these are interpreted each time they are found along a request path, they are implemented immediately without reloading the server. Second, it makes it possible to allow non-privileged users to control certain aspects of their own web content without giving them control over the entire configuration file.

This provides an easy way for certain web software, like content management systems, to configure their environment without providing access to the central configuration file. This is also used by shared hosting providers to retain control of the main configuration while giving clients control over their specific directories.

Nginx

Nginx does not interpret .htaccess files, nor does it provide any mechanism for evaluating per-directory configuration outside of the main configuration file. This may be less flexible than the Apache model, but it does have its own advantages.

The most notable improvement over the .htaccess system of directory-level configuration is increased performance. For a typical Apache setup that may allow .htaccess in any directory, the server will check for these files in each of the parent directories leading up to the requested file, for each request. If one or more .htaccess files are found during this search, they must be read and interpreted. By not allowing directory overrides, Nginx can serve requests faster by
doing a single directory lookup and file read for each request (assuming that the file is found in the conventional directory structure).

Another advantage is security related. Distributing directory-level configuration access also distributes the responsibility of security to individual users, who may not be trusted to handle this task well. Ensuring that the administrator maintains control over the entire web server can prevent some security missteps that may occur when access is given to other parties.

Keep in mind that it is possible to turn off .htaccess interpretation in Apache if these concerns resonate with you.

File vs URI-Based Interpretation

How the web server interprets requests and maps them to actual resources on the system is another area where these two servers differ.

Apache

Apache provides the ability to interpret a request as a physical resource on the filesystem or as a URI location that may need a more abstract evaluation. In general, for the former Apache uses <Directory>or <Files> blocks, while it utilizes <Location> blocks for more abstract resources.

Because Apache was designed from the ground up as a web server, the default is usually to interpret requests as filesystem resources. It begins by taking the document root and appending the portion of the request following the host and port number to try to find an actual file. Basically, the filesystem hierarchy is represented on the web as the available document tree.

Apache provides a number of alternatives for when the request does not match the underlying filesystem. For instance, an Alias directive can be used to map to an alternative location. Using <Location>blocks is a method of working with the URI itself instead of the filesystem. There are also regular expression variants which can be used to apply configuration more flexibly throughout the filesystem.

While Apache has the ability to operate on both the underlying filesystem and the webspace, it leans heavily towards filesystem methods. This can be seen in some of the design decisions, including the use of .htaccess files for per-directory configuration. The Apache docs themselves warn against using URI-based blocks to restrict access when the request mirrors the underlying filesystem.

Nginx

Nginx was created to be both a web server and a proxy server. Due to the architecture required for these two roles, it works primarily with URIs, translating to the filesystem when necessary.

This can be seen in some of the ways that Nginx configuration files are constructed and interpreted.Nginx does not provide a mechanism for specifying configuration for a filesystem directory and instead parses the URI itself.

For instance, the primary configuration blocks for Nginx are server and location blocks. The serverblock interprets the host being requested, while the location blocks are responsible for matching portions of the URI that comes after the host and port. At this point, the request is being interpreted as a URI, not as a location on the filesystem.

For static files, all requests eventually have to be mapped to a location on the filesystem. First, Nginx selects the server and location blocks that will handle the request and then combines the document root with the URI, adapting anything necessary according to the configuration specified.

This may seem similar, but parsing requests primarily as URIs instead of filesystem locations allows Nginx to more easily function in both web, mail, and proxy server roles. Nginx is configured simply by laying out how to respond to different request patterns. Nginx does not check the filesystem until it is ready to serve the request, which explains why it does not implement a form of .htaccess files.

Modules

Both Nginx and Apache are extensible through module systems, but the way that they work differ significantly.

Apache

Apache’s module system allows you to dynamically load or unload modules to satisfy your needs during the course of running the server. The Apache core is always present, while modules can be turned on or off, adding or removing additional functionality and hooking into the main server.

Apache uses this functionality for a large variety tasks. Due to the maturity of the platform, there is an extensive library of modules available. These can be used to alter some of the core functionality of the server, such as mod_php, which embeds a PHP interpreter into each running worker.

Modules are not limited to processing dynamic content, however. Among other functions, they can be used used for rewriting URLs, authenticating clients, hardening the server, logging, caching, compression, proxying, rate limiting, and encrypting. Dynamic modules can extend the core functionality considerably without much additional work.

Nginx

Nginx also implements a module system, but it is quite different from the Apache system. In Nginx, modules are not dynamically loadable, so they must be selected and compiled into the core software.

For many users, this will make Nginx much less flexible. This is especially true for users who are not comfortable maintaining their own compiled software outside of their distribution’s conventional packaging system. While distributions’ packages tend to include the most commonly used modules, if you require a non-standard module, you will have to build the server from source yourself.

Nginx modules are still very useful though, and they allow you to dictate what you want out of your server by only including the functionality you intend to use. Some users also may consider this more secure, as arbitrary components cannot be hooked into the server. However, if your server is ever put in a position where this is possible, it is likely compromised already.

Nginx modules allow many of the same capabilities as Apache modules. For instance, Nginx modules can provide proxying support, compression, rate limiting, logging, rewriting, geolocation, authentication, encryption, streaming, and mail functionality.

Support, Compatibility, Ecosystem, and Documentation

A major point to consider is what the actual process of getting up and running will be given the landscape of available help and support among other software.

Apache

Because Apache has been popular for so long, support for the server is fairly ubiquitous. There is a large library of first- and third-party documentation available for the core server and for task-based scenarios involving hooking Apache up with other software.

Along with documentation, many tools and web projects include tools to bootstrap themselves within an Apache environment. This may be included in the projects themselves, or in the packages maintained by your distribution’s packaging team.

Apache, in general, will have more support from third-party projects simply because of its market share and the length of time it has been available. Administrators are also somewhat more likely to have experience working with Apache not only due to its prevalence, but also because many people start off in shared-hosting scenarios which almost exclusively rely on Apache due to the .htaccess distributed management capabilities.

Nginx

Nginx is experiencing increased support as more users adopt it for its performance profile, but it still has some catching up to do in some key areas.

In the past, it was difficult to find comprehensive English-language documentation regarding Nginx due to the fact that most of the early development and documentation were in Russian. As interest in the project grew, the documentation has been filled out and there are now plenty of administration resources on the Nginx site and through third parties.

In regards to third-party applications, support and documentation is becoming more readily available, and package maintainers are beginning, in some cases, to give choices between auto-configuring for Apache and Nginx. Even without support, configuring Nginx to work with alternative software is usually straight-forward so long as the project itself documents its requirements (permissions, headers, etc).

Using Apache and Nginx Together

After going over the benefits and limitations of both Apache and Nginx, you may have a better idea of which server is more suited to your needs. However, many users find that it is possible to leverage each server’s strengths by using them together.

The conventional configuration for this partnership is to place Nginx in front of Apache as a reverse proxy. This will allow Nginx to to handle all requests from clients. This takes advantage of Nginx’s fast processing speed and ability to handle large numbers of connections concurrently.

For static content, which Nginx excels at, the files will be served quickly and directly to the client. For dynamic content, for instance PHP files, Nginx will proxy the request to Apache, which can then process the results and return the rendered page. Nginx can then pass the content back to the client.

This setup works well for many people because it allows Nginx to function as a sorting machine. It will handle all requests it can and pass on the ones that it has no native ability to serve. By cutting down on the requests the Apache server is asked to handle, we can alleviate some of the blocking that occurs when an Apache process or thread is occupied.

This configuration also allows you to scale out by adding additional backend servers as necessary. Nginx can be configured to pass to a pool of servers easily, increasing this configuration’s resilience to failure and performance.

Conclusion

As you can see, both Apache and Nginx are powerful, flexible, and capable. Deciding which server is best for you is largely a function of evaluating your specific requirements and testing with the patterns that you expect to see.

There are differences between these projects that have a very real impact on the raw performance, capabilities, and the implementation time necessary to get each solution up and running. However, these usually are the result of a series of trade offs that should not be casually dismissed. In the end, there is no one-size-fits-all web server, so use the solution that best aligns with your objectives.

Apache Httpd web page authentication

this command for create user and password access file:
htpasswd -c /etc/httpd/conf/.htpasswd xxxx

chown root:apache /etc/httpd/conf/.htpasswd
chmod 640 /etc/httpd/conf/.htpasswd

In my vhost configuration file:


ServerName sm.saic.it
RewriteEngine On
DocumentRoot /usr/local/sendmailanalyzer/www
Options ExecCGI
AddHandler cgi-script .cgi
DirectoryIndex sa_report.cgi

AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/httpd/conf/.htpasswd
Require valid-user

# Apache 2.4
# Require all granted
#Require host example.com


# Apache 2.2
Order deny,allow
#Allow from all
#Allow from 127.0.0.1
#Allow from ::1
# Allow from .example.com


Fail2ban and wordpress

Find the wordpress log file.

normally is configured in httpd.conf (if u are using apache web server)
Find the wordpress log file.
normally is configured in httpd.conf (if u are using apache web server)

    # The following directives define some format nicknames for use with
    # a CustomLog directive (see below).
    #

    #LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    LogFormat "%h %v %l %u %t \"%r\" %>s %b" comonvhost

    
      # You need to enable mod_logio.c to use %I and %O
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio

    
    #
    # The location and format of the access logfile (Common Logfile Format).
    # If you do not define any access logfiles within a 
    # container, they will be logged here.  Contrariwise, if you *do*
    # define per- access logfiles, transactions will be
    # logged therein and *not* in this file.
    #
    #CustomLog "logs/access_log" common
    #
    # If you prefer a logfile with access, agent, and referer information
    # (Combined Logfile Format) you can use the following directive.
    #
    CustomLog "logs/access_log" combined

here the log file parameters

My server example of failed login to wordpress


%v       %h                     %l %u %t                     \"%r\"                        %>s
saic.it 85.10.117.176 - -       [30/Sep/2017:09:29:02 +0200] "POST /wp-login.php HTTP/1.1" 200 
%b   \"%{Referer}i\"                   \"%{User-Agent}i\""
5444 "http://www.saic.it/wp-login.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0) Gecko/20100101 Firefox/52.0"

Link

Link2

Install dependencies for JQuery into Angular2

3 Steps:
Install jQuery. (skip if already installed)
npm install jquery –save
Install types for jQuery.
npm install @types/jquery –save
Import jQuery in app.module.ts.
import * as $ from ‘jquery’;
The best way to enable the production mode for an Angular 2 application, is to use angular-cli and build the application with ng build -prod. This will build the application with production profile. Using angular-cli has the benefit of being able to use development mode using ng serve or ng build while developing without altering the code all the time.

How to test if the email address exists

Source Link

To check if user entered email mailbox.does.not.exist@webdigiapps.com really exists go through the following in command prompt on windows / terminal on mac. The commands you type in are in green and the server response is in blue. Please refer to MAC & PC screenshots towards the end of this post.

Step 1 – Find mail exchanger or mail server of webdigiapps.com

COMMAND:
nslookup -q=mx webdigiapps.com
RESPONSE:
Non-authoritative answer:
webdigiapps.com mail exchanger = 0 mx2.sub3.homie.mail.dreamhost.com.
webdigiapps.com mail exchanger = 0 mx1.sub3.homie.mail.dreamhost.com.

Step 2 – Now we know the mail server address so let us connect to it. You can connect to one of the exchanger addresses in the response from Step 1.

COMMAND:
telnet mx2.sub3.homie.mail.dreamhost.com 25
RESPONSE:
Connected to mx2.sub3.homie.mail.dreamhost.com.
Escape character is ‘^]’.
220 homiemail-mx7.g.dreamhost.com ESMTP

COMMAND:
helo hi
RESPONSE:
250 homiemail-mx8.g.dreamhost.com

COMMAND:
mail from: <youremail@gmail.com>
RESPONSE:
250 2.1.0 Ok

COMMAND:
rcpt to: <mailbox.does.not.exist@webdigiapps.com>
RESPONSE:
550 5.1.1 <mailbox.does.not.exist@webdigiapps.com>: Recipient address rejected: User unknown in virtual alias table

COMMAND:
quit
RESPONSE:
221 2.0.0 Bye

Screenshots – MAC Terminal & Windows

MAC email verification
Windows email verification

NOTES:

1) the 550 response indicates that the email address is not valid and you have caught a valid but wrong email address. This code can be on the server and called on AJAX when user tabs out of the email field.  The entire check will take less than 2 seconds to run and you can make sure that the email is correct.
2) If email was present the server will respond with a 250 instead of 550
3) There are certain servers with a CATCH ALL email and this means all email address are accepted as valid on their servers (RARE but some servers do have this setting).
4) Please do not use this method to continuously to check for availability of gmail / yahoo / msn accounts etc as this may cause your IP to be added to a blacklist.
5) This is to supplement the standard email address javascript validation.

IPTables – Load Balance Incoming Web Traffic

First of ALL

The important thing to remember as we go forward is that ORDER MATTERS! Rules are executed from top to bottom.

Note that Rules are applied in order of appearance, and the inspection ends immediately when there is a match. Therefore, for example, if a Rule rejecting ssh connections is created, and afterward another Rule is specified allowing ssh, the Rule to reject is applied and the later Rule to accept the ssh connection is not.

At the top of the /etc/sysconfig/iptables (Centos 7) the rules are more important !!

 

Instead of using the default policy, I normally recommend making an explicit DROP/REJECT rule at the bottom of your chain that matches everything. You can leave your default policy set to ACCEPT and this should reduce the chance of blocking all access to the server.

Load Balance Incoming Web Traffic

This uses the iptables nth extension. The following example load balances the HTTPS traffic to three different ip-address. For every 3th packet, it is load balanced to the appropriate server (using the counter 0).

iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 0 -j DNAT --to-destination 192.168.1.101:443
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 1 -j DNAT --to-destination 192.168.1.102:443
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 2 -j DNAT --to-destination 192.168.1.103:443

Allow Loopback Access

You should allow full loopback access on your servers. i.e access using 127.0.0.1

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

Allow Internal Network to External network.

On the firewall server where one ethernet card is connected to the external, and another ethernet card connected to the internal servers, use the following rules to allow internal network talk to external network.

In this example, eth1 is connected to external network (internet), and eth0 is connected to internal network (For example: 192.168.1.x).

iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT

Allow outbound DNS

The following rules allow outgoing DNS connections.

iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT

Prevent DoS Attack

The following iptables rule will help you prevent the Denial of Service (DoS) attack on your webserver.

iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT

In the above example:

  • -m limit: This uses the limit iptables extension
  • –limit 25/minute: This limits only maximum of 25 connection per minute. Change this value based on your specific requirement
  • –limit-burst 100: This value indicates that the limit/minute will be enforced only after the total number of connection have reached the limit-burst level.

Port Forwarding

The following example routes all traffic that comes to the port 442 to 22. This means that the incoming ssh connection can come from both port 22 and 422.

iptables -t nat -A PREROUTING -p tcp -d 192.168.102.37 --dport 422 -j DNAT --to 192.168.102.37:22

If you do the above, you also need to explicitly allow incoming connection on the port 422.

iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT

Log Dropped Packets

You might also want to log all the dropped packets. These rules should be at the bottom.

First, create a new chain called LOGGING.

iptables -N LOGGING

Next, make sure all the remaining incoming connections jump to the LOGGING chain as shown below.

iptables -A INPUT -j LOGGING

Next, log these packets by specifying a custom “log-prefix”.

iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables Packet Dropped: " --log-level 7

Finally, drop these packets.

iptables -A LOGGING -j DROP

(most of the rules from here)

Example:

iptables -A INPUT --jump ACCEPT --protocol all   --source 127.0.0.1
iptables -A INPUT --jump ACCEPT --protocol tcp   --dport 22
iptabels -A INPUT --jump ACCEPT --protocol icmp
iptables -A INPUT --jump ACCEPT --match state    --state ESTABLISHED,RELATED
iptables -A INPUT --jump REJECT --protocol all

 

 

Angular 2 data binding

Original Link

Angular 2 has support for these data-bindings:

  • Interpolation: One-way data binding from the component to the template. Let’s you display information from the component into the template. Example: {{person.name}}.
  • Property bindings: One-way data bindings from the component to the template. Let you bind data from the component into the template. You typically use them to bind component data to DOM element properties (like for instance the src property of an image). Example: <img [src]="person.imageUrl">.
  • Event bindings: One-way data bindings from the template to the component. Let’s you bind template events to the component. You typically use them to execute arbitrary code as a response to an interaction between the user and the user interface of your application. Example (click)="selectPerson(person)".
  • [(ngModel)]: Two-way data binding from the component to the template and vice versa. It syncs data both ways from the component to the template and back. You typically use it within form inputs. Example [(ngModel)]="person.name"

 

UPDATE (18th May 2017)This tutorial has been updated to the latest version of Angular (Angular 4). Note that the Angular team has re-branded the terms Angular 2 to Angular and Angular 1.x to AngularJS which are now the official names of these frameworks.

This is the fifth article on the Getting Started with Angular 2 Step by Step series if you missed the previous articles go and check them out!

Good morning! Time for some Angular 2 goodness! Yesterday you learned about Angular 2 Routing and today you are going to learn about how you can create forms and validate them in Angular 2.

Angular 2 Getting Started

The Code Samples

You can download all the code samples for this article from this GitHub repository.

Our Application Up Until Now

At this point in time we have developed a tiny Angular 2 application to learn more about people from the StarWars universe. We have two components, the PeopleListComponent that displays a list of people and the PersonDetailsComponent that displays more information about the character that you have selected.

We use Angular 2 routing to navigate between these two views, the list of people being our default view and the one that is rendered as soon as the application starts.

We Want to Save Our Own Data!

Up until now we’ve just been reading information and we are tired of that! We want to be able to write and save our own data.

In order to do that we are going to transform our PersonDetailsComponent into a form and add some validation on top to ensure that the information that we save is correct.

At the end of exercise, our details form should look something like this:

Angular 2 Forms and Validation

First Things First! We Need to Add The Forms Module to Our App!

From RC5 onwards we need to declare our module dependencies in NgModule and since we want to use the new forms API you’ll need to import it in our app.module.ts:

import { FormsModule } from '@angular/forms';

And specify it as a dependency via the imports property:

// imports

@NgModule({
  declarations: [
    AppComponent,
    PeopleListComponent,
    PersonDetailsComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,        // <===== HERE! :)
    HttpModule,
    AppRoutingModule,
  ],
  providers: [PeopleService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Happily for us, because we bootstrapped our project with the Angular cli this has already been handled for us. The whole app.module.ts should already look like this:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { PeopleListComponent } from './people-list/people-list.component';
import { PeopleService } from './people.service';
import { PersonDetailsComponent } from './person-details/person-details.component';

import { AppRoutingModule } from "./app-routing.module";

@NgModule({
  declarations: [
    AppComponent,
    PeopleListComponent,
    PersonDetailsComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AppRoutingModule,
  ],
  providers: [PeopleService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Ok! Now we can proceed!

Using a File Template Instead of an Inline Template

The first thing we’re going to do now that things are getting serious is to extract our PersonDetailsComponent template in its very own file. Yes you can do that!

As a starting point, I thought it was nice for you to see your template bindings beside your component API but now that we are going to be writing more HTML it is nice to have it separated in its own file and get syntax highlighting and better text editor support altogether (although depending on the editor you’re using you may get great HTML support in your TypeScript via this or this in the future).

How can we use a file template instead of an inline one?

The @Component decorator has a templateUrl property in addition to the template property that we’ve been using thus far. Taking advantage of that property we can tell Angular 2 about which HTML template we want to use with a particular component. Let’s extract our PersonDetailsComponent template into a person-details.component.html file:

  <section *ngIf="person">
    <h2>You selected: {{person.name}}</h2>
    <h3>Description</h3>
    <p>
      {{person.name}} weights {{person.weight}} and is {{person.height}} tall.
    </p>
  </section>
  <button (click)="gotoPeoplesList()">Back to peoples list</button>

And update our PersonDetailsComponent metadata:

// some imports

@Component({
  selector: 'app-person-details',
  templateUrl: './person-details.component.html',  // <=== HERE!
})
export class PersonDetailsComponent implements OnInit {
    // some code...
}

A Basic Form in Angular 2

Ok, now that we got that covered, let’s add an HTML form to our view. Angular 2 works perfectly with HTML5 standards so we are just going to create a vanilla HTML form to edit the properties that we have in our Person interface.

We update our template to look like this:

<!-- new syntax for ng-if -->
<section *ngIf="person">
  <section>
    <h2>You selected: {{person.name}}</h2>
    <h3>Description</h3>
    <p>
      {{person.name}} weights {{person.weight}} and is {{person.height}} tall.
    </p>
  </section>
  <section>
    <form>
      <div>
        <label for="name">Name: </label>
        <input type="text" name="name">
      </div>
      <div>
        <label for="weight">Weight: </label>
        <input type="number" name="weight">
      </div>
      <div>
        <label for="height">Height: </label>
        <input type="number" name="height">
      </div>
    </form>
  </section>

  <button (click)="gotoPeoplesList()">Back to peoples list</button>
<section>

Ok, now we have a basic form but we are not displaying anything. Using the stuff that we’ve learned thus far we could tie our form to our component’s person by using event and property bindings.

So, for instance, we could do the following:

<div>
    <label for="name">Name: </label>
    <input type="text"
           name="name"
           [value]="person.name"
           (change)="person.name = name.value"
           #name>
</div>

Where we use a [value] property binding to bind the component’s person.name property to the input element, and we use the (change) event binding to update our person’s name.

There’s something weird though in this particular example, and that’s the #name right there inside our input element. That’s what Angular 2 calls a template local variable and it’s often used to keep DOM element related references and logic out of our component code.

In this case, the #name variable refers to the input element itself. That’s why when Angular 2 evaluates the person.name = name.value expression our person model gets updated.

This feels like way too much work to bind a property from our component to our template and back, doesn’t it?… If only there was a better way… 🙂

ngModel and Angular 2 Two-Way Data Binding

Well there is! The ngModel data binding, very similar to AngularJS ng-model, let’s us establish a two-way data binding for a given property between the component and the template. A two-way data binding effectively syncs the value of a property between template and component forwarding changes in both directions.

The syntax is a little bit special and takes a little bit to get accustomed to:

<div>
    <label for="name">Name: </label>
    <input type="text" name="name" [(ngModel)]="person.name">
</div>

Hell yeah! You read it right: [(ngModel)]="person.name". Before you start cursing let’s spend a minute longer contemplating this piece of code…

We’ve learned that event bindings are one-directional bindings that go from the template to the underlying component and are represented in brackets (click). We’ve also learned that property bindings are one-directional bindings that go from the component to the template and are represented in square brackets [src]. Therefore if we want a two-way binding, we have something equivalent to an event binding plus a property binding, merge both syntaxes and you get the “banana-in-a-box” syntax of [(ngModel)]. Makes sense right?

The [(ngModel)] two-way data binding can indeed be decomposed into an event/property binding combo like this:

<input type="text" name="name"
  [ngModel]="model.name"
  (ngModelChange)="model.name = $event" >

In the case of normal DOM events the $event variable usually gives us access to the DOM event itself. In this particular case though, for the special (ngModelChange) custom event, it takes the value of the input being changed. If you want to learn more about ngModel and when it’s useful to decompose it take a look at the Angular 2 docs.

Ok! So now that we know that [(ngModel)] exists, we can use it in our form to create a two-way data binding for each one of the person properties (but for the id, you don’t want to change that):

  <!-- new syntax for ng-if -->
<section *ngIf="person">
  <section>
    <h2>You selected: {{person.name}}</h2>
    <h3>Description</h3>
    <p>
      {{person.name}} weights {{person.weight}} and is {{person.height}} tall.
    </p>
  </section>
  <section>
    <form>
      <div>
        <label for="name">Name: </label>
        <input type="text" name="name" [(ngModel)]="person.name">
      </div>
      <div>
        <label for="weight">Weight: </label>
        <input type="number" name="weight" [(ngModel)]="person.weight">
      </div>
      <div>
        <label for="height">Height: </label>
        <input type="number" name="height" [(ngModel)]="person.height">
      </div>
    </form>
  </section>

  <button (click)="gotoPeoplesList()">Back to peoples list</button>
</section>

If you run the application in your browser (remember ng serve --open or ng s -o if you’re cool) you’ll be able to see how whenever you change the value in these inputs the changes are reflected instantly in the description.

A Review of Angular 2 Data Bindings

With the [(ngModel)] binding we have now covered all data bindings available to you in Angular 2. Let’s make a quick recap of them before we continue with forms and validation.

Angular 2 has support for these data-bindings:

  • Interpolation: One-way data binding from the component to the template. Let’s you display information from the component into the template. Example: {{person.name}}.
  • Property bindings: One-way data bindings from the component to the template. Let you bind data from the component into the template. You typically use them to bind component data to DOM element properties (like for instance the src property of an image). Example: <img [src]="person.imageUrl">.
  • Event bindings: One-way data bindings from the template to the component. Let’s you bind template events to the component. You typically use them to execute arbitrary code as a response to an interaction between the user and the user interface of your application. Example (click)="selectPerson(person)".
  • [(ngModel)]: Two-way data binding from the component to the template and vice versa. It syncs data both ways from the component to the template and back. You typically use it within form inputs. Example [(ngModel)]="person.name".

Adding Validation to Our Form

Now that we have a way to update a person’s details let’s add some validation to ensure that the data we’re introducting is legit before we save it. We are going to do the following:

  1. Make the name field required,
  2. Display a super helpful validation error message to the user whenever the field is empty
  3. Enable/disable the form submit button based on the validity of the inputs within the form

The way we track changes and the validity of an input in Angular 2 is through the same ngModel directive that we use for two-way data binding. By using this directive with an input we can obtain information about whether or not the user has done something with the input, wether or not the value has changed and even if it is invalid.

Let’s add the required attribute to the name input to mark it as a required bit of information (One can’t live without a name):

<label for="name">Name: </label>
<input type="text" name="name" required [(ngModel)]="person.name">

Angular 2 uses the name attribute (in this case name="name") to identify this particular input and keep track of its changes and validity.

The easiest way to visualize how Angular 2 tracks changes in our input is to see how it adds/removes css classes to the input based on it’s state.

If we update the input with the following snippet of code to display the DOM className property after the input and go to the browser, you’ll be able to appreciate how as you interact with the input different classes are added:

<label for="name">Name: </label>

<!-- 1. Added #name local template variable in the input element -->
<input type="text" name="name" required [(ngModel)]="person.name" #name>

<!-- 2. Added text to show the input element className -->
<p>
 input "name" class is: {{ name.className }}
</p>

So if you:

  • leave the input untouched it will have the: ng-untouched ng-pristine ng-valid classes
  • click inside then outside the input and it will be marked as visitedand given the ng-touched class
  • type something and it will be marked as dirty and given the ng-dirty class
  • remove its whole content and it will be marked as invalid and given the ng-invalid class

Test it yourself!

We can take advantage of this feature to add some css styling to our inputs when they are valid and invalid. You can update the styles.css file to include the following styles:

// These styles are HEAVILY, HEAVILY inspired (STOLEN!!)
// from the Angular 2 docs

// valid and required show green
input.ng-valid[required] {
  border-left: 5px solid #42A948; /* green */
}

// invalid
input.ng-invalid {
  border-left: 5px solid #a94442; /* red */
}

This css file is linked within index.html. As such it represents the global styles for our application which are applied globally regardless of in which component you are in.

In the future you’ll learn that you can define component-level styles that are only applied within a component. Yey!

Back to the PersonDetailsComponent template we now want to display an error message whenever the user doesn’t type the required name. We can do that by creating a local template variable name and setting its value to ngModelHow can we do that?Although unintuitive, you do that by assigning the local template variable to ngModel like this. Update the previous snippet to the following:

<label for="name">Name: </label>
<input type="text" name="name" required [(ngModel)]="person.name" #name="ngModel">

You can think of it as a way to gain access to the directive that tracks the changes and validity of the input. Now that name holds the value of the ngModel directive, we can access its properties and find whether or not the input is in a valid state. We can use that information to toggle the visibility of an error message:

<label for="name">Name: </label>
<input type="text" name="name" required [(ngModel)]="person.name" #name="ngModel">
<div [hidden]="name.valid || name.pristine" class="error">
    Name is required my good sir/lady!
</div>

That we will style with this magic css:

.error{
  padding: 12px;
  background-color: rgba(255, 0, 0, 0.2);
  color: red;
}

Notice how using the property binding syntax we can bind any expression to the [hidden] DOM property. In this case we only hide the message when ngModel tells us that the input is valid or pristine (no reason to show the error if the user hasn’t even started editing the input).

Custom Validation FTW!

Let’s do another example of validation. This time for the input element tied to a person’s weight using the max and min HTML5 input attributes. Let’s say that our Star Wars figures shouldn’t weight less than a feather nor more than a Rancor. We’ll update our template as follows:

<label for="weight">Weight: </label>
<input type="number" name="weight" [(ngModel)]="person.weight" min=0 max=350 #weight="ngModel">

And now we add the validation messages for both constraints:

<div *ngIf="weight.errors && (weight.dirty || weight.touched)"
    class="error">
    <p [hidden]="!weight.errors.min">
      Weight must be higher than a feather's. {{weight.value}} is way too low.
    </p>
    <p [hidden]="!name.errors.max">
      Weight can't be higher than a Rancor's. {{weight.value}} is too high
    </p>
</div>

If you run the example again (remember ng serve --open) you’ll be able to verify that this new validation doesn’t work! Oh no! What do we do?

Angular 2 let’s you extend the built-in validation system with new validators of your own. Let’s create two new validators for the minand max attributes. The validators will be represented as directives which we can create with the aid of our mighty companion: The Angular CLI. You can think of a directive as a way to add custom behavior to DOM elements matching a specific selector.

Type the following:

PS> ng generate directive min-validator
# ng g d min-validator

This will create a new directive for us and register the directive into our AppModule. The new directive will look like this:

import { Directive } from '@angular/core';

@Directive({
  selector: '[appMinValidator]'
})
export class MinValidatorDirective {

  constructor() { }

}

We can change the selector to reflect the attribute that we want to tie to the validation logic (min):

import { Directive } from '@angular/core';

@Directive({
  // CSS selector for attributes
  selector: '[min]'
})
export class MinValidatorDirective {

  constructor() { }
}

In order to turn this new directive into a validator we need to implement the Validator interface which contains the validatemethod. This method will contain the validation logic that will compare the current value of the input with our attribute min value.

But before we can implement that logic we need to get a hold of the min value. We’ll do that taking advantage of the @Input decorator (if you missed previous articles in the series, you can use inputs to pass data into a component or directive) :

export class MinValidatorDirective {
  // new @Input here
  // it will get the min number from the attribute
  // For example 5 for <input min=5 ...
  @Input() min: number;

  constructor() { }
}

And now we implement the Validator interface with the validatemethod as follows:

import { Validator, AbstractControl, ValidationErrors} from '@angular/forms';

@Directive({...})
export class MinValidatorDirective implements Validator {
  // new @Input here
  // it will get the min number from the attribute
  // For example 5 for <input min=5 ...
  @Input() min: number;

  constructor() { }

  // Define validation logic
  validate(control: AbstractControl): ValidationErrors {
    const currentValue = control.value;
    const isValid = currentValue >= this.min;

    // return errors as an object
    return isValid ? null : {
      min: {
        valid: false
      }
    };
  }
}

Ok! So now we have a custom validator directive for the minattribute ready to go. We have created the directive, tied it to the minattribute via the [min] selector, implemented the validation logic via the Validator interface, registered the directive into our AppModuleso we can use it within our application but there’s one little thing that remains. We need to make Angular Validation’s system aware of this validator. We do this by registering the validator as a provider for the NG_VALIDATORS token inside the @Directive decorator metadata:

import { Validator, AbstractControl, ValidationErrors, NG_VALIDATORS} from '@angular/forms';

@Directive({
  selector: '[min]',
  // register validator in DI
  providers: [{provide: NG_VALIDATORS, useExisting: MinValidatorDirective, multi: true}]
})
export class MinValidatorDirective implements Validator {
    // code...
}

Now when the Angular validation system uses dependency injection to get a hold of all the available validators (represented by NG_VALIDATORS) in addition to the built-in validators it will also have access to this new custom validator.

You can now verify that the validation logic we wrote earlier for our weight input is now working. Test to write a weight of -100 and you’ll be greeted by an error message. Yippi!

Now we can repeat the steps for the max validator. Let’s be cool and do the shorthand with the Angular CLI:

PS> ng g d max-validator

And write the validator logic:

import { Directive, Input } from '@angular/core';
import { Validator, AbstractControl, ValidationErrors, NG_VALIDATORS } from '@angular/forms';

@Directive({
  selector: '[max]',
  // register validator in DI
  providers: [{provide: NG_VALIDATORS, useExisting: MaxValidatorDirective, multi: true}]
})
export class MaxValidatorDirective implements Validator {
  @Input() max: number;

  validate(control: AbstractControl): ValidationErrors {
    const currentValue = control.value;
    const isValid = currentValue <= this.max;

    // return errors as an object
    return isValid ? null : {
      max: {
        valid: false
      }
    };

  }

  constructor() { }

}

Tada! Now we have our very own custom validators for min and max, Great job!

Submitting Our Form

Ok! Let’s do a quick summary! Up to this point we have added some validation to the name input within our form so that if the user removes the name we will show an error because you are not supposed to do that with a required field. We’ve also added min and max validation to our weight attribute and some basic styles.

The next step is to actually try to save these changes. To that end, we are going to add a submit button inside our form:

  <section>
    <form>
      <!--- form inputs here ...--->

      <!-- add button -->
      <button type="submit">Save</button>
    </form>
  </section>

And we need to disable it when the form is invalid so that the user can’t save corrupted/invalid data, cause chaos, mayhem and destroy our beloved servers (although you and I know that you must have this type of validation in your service layer as well as in your client).

In order to do that we create yet another local template variable #personForm to get access to the actual form via the ngFormdirective. We then use that variable to disable the button when the form is invalid:

  <section>
    <form #personForm="ngForm">
      <div>
          <!-- inputs ... -->
      </div>
      <button type="submit" [disabled]="!personForm.form.valid">Save</button>
    </form>
  </section>

Finally we set a submit event binding in the form so that we can save our person details whenever we submit the form:

  <section>
    <form (ngSubmit)="savePersonDetails()" #personForm="ngForm">
      <div>
          <!-- inputs ... -->
      </div>
      <button type="submit" [disabled]="!personForm.form.valid">Save</button>
    </form>
  </section>

The whole template now looks like this:

<section *ngIf="person">
  <!-- description -->
  <section>
    <h2>You selected: {{person.name}}</h2>
    <h3>Description</h3>
    <p>
      {{person.name}} weights {{person.weight}} and is {{person.height}} tall.
    </p>
  </section>

  <!-- form -->
  <section>
    <form (ngSubmit)="savePersonDetails()" #personForm="ngForm">
      <div>
        <label for="name">Name: </label>
        <input type="text" name="name" [(ngModel)]="person.name" required #name="ngModel">
        <div [hidden]="name.valid || name.pristine" class="error">
            Name is required my good sir/lady!
        </div>
      </div>
      <div>
        <label for="weight">Weight: </label>
        <input type="number" name="weight" [(ngModel)]="person.weight" min=0 max=350 #weight="ngModel">
        <div *ngIf="weight.errors && (weight.dirty || weight.touched)"
            class="error">
            <p [hidden]="!weight.errors.min">
              Weight must be bigger than a feather's. {{weight.value}} is way too low.
            </p>
            <p [hidden]="!weight.errors.max">
              Weight can't be bigger than a Rancor's. {{weight.value}} is too high
            </p>
        </div>
      </div>
      <div>
        <label for="height">Height: </label>
        <input type="number" name="height" [(ngModel)]="person.height">
      </div>
      <div>
        <label for="profession">Profession:</label>
        <select name="profession" [(ngModel)]="person.profession">
          <option *ngFor="let profession of professions" [value]="profession">{{profession}}</option>
        </select>
      </div>


      <button type="submit" [disabled]="!personForm.form.valid">Save</button>
    </form>
  </section>

  <button (click)="gotoPeoplesList()">Back to peoples list</button>
<section>

We just need to update our PersonDetailsComponent to be able to handle that submit event:

// imports 

@Component({
  selector: 'app-person-details',
  templateUrl: './person-details.component.html',
  styles: []
})
export class PersonDetailsComponent implements OnInit {
    // codes...

    savePersonDetails(){
        alert(`saved!!! ${JSON.stringify(this.person)}`);
    }
}

And now if you test everything that you’ve just done in the browser: Click on Luke Skywalker, change his name to Luke Vader (moahahaha), then save, you should be able to see your changes in an alert box.

Let’s update our component further so we can save this information with the help of our PeopleService.

Saving Information

This has nothing to do with forms and validation so I’ll just run wild like the wind over it without much detail. We are going to add a savemethod in our service and then we are going to save the changes we’ve done on a person in memory within our service.

We start by updating the PersonDetailsComponent:

// etc
export class PersonDetailsComponent implements OnInit {
    savePersonDetails(){
      this.peopleService.save(this.person);
    }

And then we update our PeopleService with the new save method:

import { Injectable } from '@angular/core';
import { Person } from './person';

const PEOPLE : Person[] = [
      {id: 1, name: 'Luke Skywalker', height: 177, weight: 70, profession: ''},
      {id: 2, name: 'Darth Vader', height: 200, weight: 100, profession: ''},
      {id: 3, name: 'Han Solo', height: 185, weight: 85, profession: ''},
    ];

@Injectable()
export class PeopleService{

  getAll() : Person[] {
    return PEOPLE.map(p => this.clone(p));
  }
  get(id: number) : Person {
    return this.clone(PEOPLE.find(p => p.id === id));
  }
  save(person: Person){
    let originalPerson = PEOPLE.find(p => p.id === person.id);
    if (originalPerson) Object.assign(originalPerson, person);
    // saved moahahaha
  }

  private clone(object: any){
    // hack
    return JSON.parse(JSON.stringify(object));
  }
}

If you are a very observant person you’ll see that I have added the clone method to this service. The purpose of this mighty teeny tiny method is to avoid sharing the same object references between the different components in the app so that we can simulate “saving” in a way more faithful to reality.

What’s With NgModel and NgForm?

If you are a little bit like me, you are probably slightly confused with the ngModel and ngForm directives. So let’s do some recap about them:

ngModel

  • ngModel lets you track the state and validity of your inputs
  • ngModel adds css classes to your inputs based on their state, whether they have been touched, changed or whether they are valid or not.
  • Using #name="ngModel" in an input element creates a local template variable called #name and assigns the ngModeldirective to it. You can then use the variable to access the ngModel directive properties like validpristinetouched, etc.

ngForm

  • Angular 2 attaches an NgForm directive to every form element.
  • The ngForm directive exposes the form.valid property that let’s you know if all controls within a given form are in a valid state.

ngModel and ngForm

  • Whenever you add the ngModel directive to an input Angular 2 is going to register it using that name that you provide (remember name="name") with an NgForm directive that Angular 2 automagically attaches to any form element.
  • The ngForm directive contains a collection of the controls created using the ngModel directive.

Hope that makes it more clear! If you want to learn more about the ngForm directive then you may want to take a look at the Angular 2 docs

Bonus Exercise. Adding a Select Input in Angular 2

As a bonus exercise let’s try to add a select input with Angular 2 to select the profession of our Star Wars figures. An HTML5 selectelement, also known as dropdown or listbox in UI circles typically has a select element that wraps a collection of option elements.

We will start by adding a profession to the Person interface:

export interface Person {
  id: number;
  name: string;
  height: number;
  weight: number;

  // it is optional because I know it
  // doesn't exist in the API that we will
  // consume in the next exercise :)
  profession?: string;
}

Then we update our PersonDetailsComponent to include all the available professions:

export class PersonDetailsComponent implements OnInit {
    professions: string[] = ['jedi', 'bounty hunter', 'princess', 'sith lord'];
    // other code
}

And finally we update the PersonDetailsComponent template to include the select element:

<!-- description header ... -->
  <section>
    <form (ngSubmit)="savePersonDetails()" #personForm="ngForm">
      <div>
      <! -- old inputs ... -->
      <!-- ...and the new select element -->
      <div>
        <label for="profession">Profession:</label>
        <select name="profession" [(ngModel)]="person.profession">
          <option *ngFor="let profession of professions" [value]="profession">{{profession}}</option>
        </select>
      </div>
      <button type="submit" [disabled]="!personForm.form.valid">Save</button>
    </form>
  </section>

And that’s it! You can now go back to the form, click on Luke Skywalker, make him a LORD SITH, save, and who’s gonna know what’s gonna happpen in the next Star Wars movie.

Do You Want to Learn More About Forms?

Would you like to learn more about Angular 2 forms, then check any of these articles:

And by the by, if you haven’t checked it yet, take a look at this awesome course on Angular 2 at Pluralsight: Angular 2: First Look by the one and only John Papa

Concluding

Great! We have got to the end of yet another article. Now you can coun forms and validation as one more of your Angular 2 ninja skills.

Up next! Consuming a real service using Angular 2 Http.

An Aside: Oh No! I Haven’t Had Time To Update To The New Forms API! Can I Update to RC5?

If you haven’t had time to update to the new forms API but still want to start using RC5, you can enable the old forms by importing the DeprecatedFormsModule and adding it to your app.module.ts:

import {DeprecatedFormsModule} from @angular/common;

@NgModule({
  imports: [ BrowserModule, routing, DeprecatedFormsModule ],
  declarations: [ AppComponent, PeopleListComponent, PersonDetailsComponent],
  bootstrap: [ AppComponent ]
})
export class AppModule { }