Wednesday, October 22, 2025

Powershell script to bring news from news Feeds and create a nice looking HTML page.



# ===== DailyNews.ps1 =====




# RSS feed URLs

$techFeeds = @(

"https://techcrunch.com/feed/",

"https://feeds.arstechnica.com/arstechnica/index"

)

$propertyFeeds = @(

"https://www.abc.net.au/news/feed/52278/rss.xml"

)




# Output HTML file

$outputFile = "C:\temp\DailyNews.html"




# Current date

$date = (Get-Date).ToString("dddd, MMM dd yyyy")




# Function to fetch feed items

function Get-FeedItems {

param($url)




Write-Host $url

try {

$rss = [xml](Invoke-WebRequest -Uri $url -UseBasicParsing -ErrorAction Stop).Content

$items = @()

foreach ($item in $rss.rss.channel.item | Select-Object -First 5) {

$items += [PSCustomObject]@{

Title = $item.title

Link = $item.link

PubDate = $item.pubDate

Source = $rss.rss.channel.title

}

}

return $items

} catch {

Write-Host "⚠️ Could not fetch: $url"

return @([PSCustomObject]@{

Title = "⚠️ Could not fetch"

Link = $url

PubDate = ""

Source = ""

})

}

}




# Fetch items

$techNews = @()

foreach ($feed in $techFeeds) {

$techNews += Get-FeedItems $feed

}




$propertyNews = @()

foreach ($feed in $propertyFeeds) {

$propertyNews += Get-FeedItems $feed

}







# Build HTML content

$html = @"

<html>

<head>

<title>📰 Daily Tech & Property News - $date</title>

<style>

body { font-family: Segoe UI, Arial; background: #f9fafb; color: #333; margin: 20px; }

h1, h2 { color: #2a7ae2; }

a { text-decoration: none; color: #0078d7; }

a:hover { text-decoration: underline; }

section { margin-bottom: 40px; }

.article { margin: 8px 0; }

footer { margin-top: 40px; font-size: 12px; color: #777; }

</style>

</head>

<body>

<h1>📰 Daily Tech & Property News</h1>

<p><b>Date:</b> $date</p>




<section>

<h2>🏠 Property News</h2>

<ul>

"@




foreach ($item in $propertyNews) {

$html += "<li class='article'><a href='$($item.Link)' target='_blank'>$($item.Title)</a></li>`n"

}




$html += @"

</ul>

</section>




<section>

<h2>💻 Tech News</h2>

<ul>

"@




foreach ($item in $techNews) {

$html += "<li class='article'><a href='$($item.Link)' target='_blank'>$($item.Title)</a></li>`n"

}




$html += @"

</ul>

</section>




<footer>Generated automatically by PowerShell – $date</footer>

</body></html>

"@




# Save HTML

$html | Out-File -FilePath $outputFile -Encoding utf8

Write-Host "✅ HTML News Summary saved to $outputFile"

Tuesday, September 2, 2025

Springboot - Authenticating Microsoft Token

 A JWT has 3 parts (Base64URL encoded, separated by dots):

<header>.<payload>.<signature>



Create a POSTMan POST request to get MS token:

POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token

Send the below params in x-www.-form-urlencoded:


client_id: <id of application>
client_secret: <generated secret of that app>
score: api://<tenant-id>/.default
grant_type : client_credentials


The response would be :

{
    "token_type": "Bearer",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "access_token": "eyJ0eXAiOiJKV1QiL................."
}



Copy that access_token and get ready for actual API request:

https://<applicationurl>/<apiname>/<operationname>

For ex
https://tap/tcaservice/myapi

Send that access token as Bearer Token under Authentication Header

Here is the code for Token validation

@Component
public class MicrosoftTokenFilter extends OncePerRequestFilter {

    private final JwtDecoder jwtDecoder;

    public MicrosoftTokenFilter(@Value("${azure.ad.tenant-id}") String tenantId) {
        //String issuerUri = "https://login.microsoftonline.com/" + tenantId + "/v2.0";
        String issuerUri = "https://sts.windows.net/" + tenantId + "/";
        this.jwtDecoder = JwtDecoders.fromIssuerLocation(issuerUri);
    }

 @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        logger.info("Starting MicrosoftTokenFilter");
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);

            logger.info(" token = " + token);
            try {
                Jwt jwt = jwtDecoder.decode(token);

                SetupAuthentication(jwt);

            } catch (Exception e) {
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Microsoft token");
                return;
            }
        }

        filterChain.doFilter(request, response);
    }

    private void SetupAuthentication(Jwt jwt) {

            Map<String, Object> claims = jwt.getClaims();

            String name = "";
            String email = "";
            String orgCode = "";
            boolean isAuthUser = false;
            String environment = "TEST";
            String orgName = "";

            List<Role> roles = new ArrayList<Role>();
            for ( Map.Entry<String,Object> claim : claims.entrySet()) {

                if (claim.getKey().equals("EMAIL")) {
                    email = claim.getValue().toString();
                }
            }

            //set faked
            name = "Naas api";
            email = "vkumar@austroads.gov.au";
            orgCode = "Naas";
            isAuthUser = true;
            environment = "TEST";
            orgName = "Austroads";

            if (isAuthUser) {
                User user = new User();
                user.setFirstName("");
                user.setLastName(name);
                user.setEmail(email);
                user.setOrganisationCode(orgCode);
                user.setRoles(roles);
                user.setOrganisationName(orgName);


                Authentication authentication = createAuthentication(jwt, user, environment);
                setAuthentication(authentication);


                logger.info("Authorities set in context:" + SecurityContextHolder.getContext().getAuthentication().getAuthorities());

            }
    }

    private Authentication createAuthentication(Jwt jwt, User user, String environment) {      
        List authList = new ArrayList();  
        authList.add(new SimpleGrantedAuthority("TEST_MyAdminRole");
    JwtAuthenticationToken usertoken = new JwtAuthenticationToken(jwt, authList);
        return usertoken;      
    }

    private void setAuthentication(Authentication authentication) {
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(authentication);
        SecurityContextHolder.setContext(context);
    }

}



Wednesday, August 27, 2025

Azure API Management tool

API: Application Programming Interface.  









The API Gateway pattern is a design pattern used in distributed systems, especially in microservices architecture, to provide a single-entry point for all client requests. Instead of clients calling each microservice directly, they send requests to the API Gateway, which then routes, transforms, secures, and aggregates responses from backend services.


Uploading: 238449 of 238449 bytes uploaded.





Popular tools:

  • Azure API Management (APIM) – what you’re learning now.

  • AWS API Gateway

  • Kong, Apigee, NGINX, Tyk, Traefik, Spring Cloud Gateway

Analogyy:

Think of an API Gateway as a reception desk: visitors (clients) arrive at one desk, state their needs, and the receptionist handles the internal coordination with different departments (other APIS) before giving the visitor a consolidated response.


Core Functions of an API Gateway:

  • Request routing – Directing incoming calls to appropriate backend services
  • Authentication and authorization – Verifying identities and access rights before allowing requests
  • Traffic management – Controlling request flow to prevent system overload
  • Response caching – Storing frequently requested data to improve performance
  • Request/response transformation – Modifying data formats to ensure compatibility
  • Logging and monitoring – Tracking usage patterns and system health

Azure API Management:

 APIM is a tool by Microsoft Azure which works based on API Gateway pattern.

Core Features of APIM:

  • API Gateway: Acts as an entry point for API requests, handling routing, load balancing, and caching.
  • Developer Portal: Provides a customizable interface for developers to discover, learn about, and consume your APIs.
  • Management Plane: Allows API providers to manage APIs, set policies, define security measures, and monitor performance.
Components of APIM:






Tuesday, April 22, 2025

Add Emojis ti your code - Shortcut

In  visual studio 2022, you can add emojis like checkmark, smile and others in the code or logs to spruce  up your logs or comments. 


Shortcut Windows + ;

Search and chose name . 

For example 0 fire, checkmark


Monday, April 7, 2025

Authentication in .NET

 

TypeCommon Use CaseToken Type / Auth Flow
JWT Bearer TokenAPIs, SPAs, Mobile AppsToken-based (Stateless)
Cookie AuthenticationWeb Apps (MVC / Razor Pages)Cookie-based (Stateful)
OAuth2 / OpenID ConnectSocial Login, Enterprise SSOExternal Identity Providers
API Key AuthSimple Public APIsKey in Header/Query
Windows AuthenticationIntranet apps, Enterprise networks (AD/LDAP)Windows/Kerberos
Certificate AuthenticationHigh-security APIs (B2B)X.509 client certs
Custom Token / HMACLegacy systems, Highly controlled environmentsCustom logic




What does JWT Has 

JWT - JSON Web Token has 3 parts
Header  - metdata information
Payload  - User centric inform
Signature - 

Tuesday, April 1, 2025

Count colored cells in Google sheets - create custom formula

In the google sheets, use the following script and enjoy the function to count the colored cells 

=countColoredCells(B59:AF59, "#274e13")  #Green color code


 function countColoredCells(countRange,colorRef) {

  var count = 0;

  var activeRange = SpreadsheetApp.getActiveRange();

  var activeSheet = activeRange.getSheet();
  var formula = activeRange.getFormula();
 
  var rangeA1Notation = formula.match(/\((.*)\,/).pop();
  var range = activeSheet.getRange(rangeA1Notation);
  var bg = range.getBackgrounds();
  var values = range.getValues();
   
  for(var i=0;i<bg.length;i++)
    for(var j=0;j<bg[0].length;j++)
    {
      if( bg[i][j] == colorRef )
        count=count+1;
    }  
  return count;
};

Tuesday, March 25, 2025

Creating a Dental Application Front End using Angular

1. First install Nodejs from nodejs.org

2. Download and Install VSCode

3. After installing nodejs, set path environment 



4. Set the Path to nodejs







5. Then in terminal the following error occurs if we try to check "npm install" as npm is not added. 



npm : File C:\Program Files\nodejs\npm.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.

At line:1 char:1

+ npm

+ ~~~

    + CategoryInfo          : SecurityError: (:) [], PSSecurityException

    + FullyQualifiedErrorId : UnauthorizedAccess


6. Run the following command:

Set-ExecutionPolicy RemoteSigned


7. Install Angular CLI using 

npm install -g @angular/cli


8. ng new mydental   


9. cd mydenal

10. ng serve mydental

11. For better UI, lets add Angular Material 

ng add @angular/material


12. Create your first component

ng generate component dashboard