diff --git a/BlogPost/.classpath b/BlogPost/.classpath
new file mode 100644
index 0000000..906bfce
--- /dev/null
+++ b/BlogPost/.classpath
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BlogPost/.project b/BlogPost/.project
new file mode 100644
index 0000000..6b49b98
--- /dev/null
+++ b/BlogPost/.project
@@ -0,0 +1,28 @@
+
+
+ BlogPost
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+ org.springframework.ide.eclipse.boot.validation.springbootbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/BlogPost/.settings/org.eclipse.core.resources.prefs b/BlogPost/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..365bbd6
--- /dev/null
+++ b/BlogPost/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding//src/test/java=UTF-8
+encoding/=UTF-8
diff --git a/BlogPost/.settings/org.eclipse.jdt.core.prefs b/BlogPost/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..0ada971
--- /dev/null
+++ b/BlogPost/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/BlogPost/.settings/org.springframework.ide.eclipse.prefs b/BlogPost/.settings/org.springframework.ide.eclipse.prefs
new file mode 100644
index 0000000..e587c65
--- /dev/null
+++ b/BlogPost/.settings/org.springframework.ide.eclipse.prefs
@@ -0,0 +1,2 @@
+boot.validation.initialized=true
+eclipse.preferences.version=1
diff --git a/BlogPost/pom.xml b/BlogPost/pom.xml
new file mode 100644
index 0000000..42de451
--- /dev/null
+++ b/BlogPost/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+
+ com.example
+ blogpost
+ 0.0.1-SNAPSHOT
+ jar
+
+ BlogPost
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.2.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-client
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.webjars
+ js-cookie
+ 2.1.0
+
+
+ org.webjars
+ jquery
+ 2.1.1
+
+
+ org.webjars
+ bootstrap
+ 3.2.0
+
+
+ org.webjars
+ webjars-locator-core
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/BlogPost/src/main/java/com/example/BlogPost.java b/BlogPost/src/main/java/com/example/BlogPost.java
new file mode 100644
index 0000000..be01123
--- /dev/null
+++ b/BlogPost/src/main/java/com/example/BlogPost.java
@@ -0,0 +1,46 @@
+package com.example;
+
+public class BlogPost {
+ private int userId;
+ private String title;
+ private String body;
+
+ public BlogPost() {
+ }
+
+ public BlogPost(int userId, String title, String body) {
+ this.userId = userId;
+ this.title = title;
+ this.body = body;
+ }
+
+
+ public int getUserId() {
+ return userId;
+ }
+
+ public void setUserId(int userId) {
+ this.userId = userId;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+ @Override
+ public String toString() {
+ return "Blog Post [userId=" +userId + ", title=" +title +", body=" +body +"]";
+ }
+}
diff --git a/BlogPost/src/main/java/com/example/BlogPostApp.java b/BlogPost/src/main/java/com/example/BlogPostApp.java
new file mode 100644
index 0000000..1950367
--- /dev/null
+++ b/BlogPost/src/main/java/com/example/BlogPostApp.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.validation.Valid;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.security.oauth2.core.user.OAuth2User;
+import org.springframework.security.web.authentication.HttpStatusEntryPoint;
+import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@SpringBootApplication
+@RestController
+public class BlogPostApp extends WebSecurityConfigurerAdapter {
+ @Autowired
+ private BlogPostService blogService;
+
+ @RequestMapping("/user")
+ public Map user(@AuthenticationPrincipal OAuth2User principal) {
+ return Collections.singletonMap("name", principal.getAttribute("name"));
+ }
+
+ @RequestMapping(value= {"/posts", "/posts/{numberOfPosts}"})
+ public String getBlogPosts(@PathVariable(required = false) Optional numberOfPosts,
+ @RequestParam(required = false) Integer userId) {
+ if (numberOfPosts.isPresent()) {
+ //System.out.println("numberOfPosts="+numberOfPosts);
+ return blogService.getUserBlogPosts(numberOfPosts);
+ }
+ else if (userId == null){
+ //System.out.println("about to getAllBlogPosts...");
+ return blogService.getAllBlogPosts();
+ }
+ else {
+ //System.out.println("userId="+userId);
+ return blogService.getUserIdPosts(userId);
+ }
+ }
+
+ @RequestMapping("/posts/1/comments")
+ public String getAllComments() {
+ return blogService.getAllComments();
+ }
+
+ @RequestMapping("/comments")
+ public String getPostIdComments(@RequestParam int postId) {
+ return blogService.getPostIdComments(postId);
+ }
+ /*
+ @RequestMapping(value="/posts")
+ public String getUserIdPosts(@PathVariable int userId) {
+ return blogService.getUserIdPosts(userId);
+ }
+ */
+ @PostMapping("/posts")
+ public String createPost(@RequestParam("userId") int userId, //assumes auto-increment is on so no id needed
+ @RequestParam("title") String title,
+ @RequestParam("body") String body,
+ ModelMap newBlogPost) {
+ System.out.println("userId="+userId+", title="+title +", body="+body);
+ newBlogPost.putIfAbsent("userId",userId);
+ newBlogPost.putIfAbsent("title",title);
+ newBlogPost.putIfAbsent("body",body);
+ return blogService.addPost(newBlogPost);
+ }
+
+ @PutMapping("/posts/{postId}")
+ public String putPost(@RequestParam("postId") Integer postId,
+ @RequestParam("userId") Integer userId,
+ @RequestParam("title") String title,
+ @RequestParam("body") String body,
+ ModelMap oldBlogPost) {
+ oldBlogPost.put("userId",userId);
+ oldBlogPost.put("title",title);
+ oldBlogPost.put("body",body);
+ return blogService.updatePost(oldBlogPost);
+ }
+
+ @PatchMapping("/posts/{postId}")
+ public String patchPost(@RequestParam("postId") Integer postId,
+ @RequestParam("userId") Integer userId,
+ @RequestParam("title") String title,
+ @RequestParam("body") String body,
+ ModelMap oldBlogPost) {
+ oldBlogPost.put("userId",userId);
+ oldBlogPost.put("title",title);
+ oldBlogPost.put("body",body);
+ return blogService.updatePost(oldBlogPost);
+ }
+
+ @DeleteMapping("/posts/{postId}")
+ public String deletePost(@RequestParam("postId") Integer postId) {
+ return blogService.deletePost(postId);
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ // @formatter:off
+ http
+ .authorizeRequests(a -> a
+ .antMatchers("/", "/error", "/webjars/**").permitAll()
+ .anyRequest().authenticated()
+ )
+ .exceptionHandling(e -> e
+ .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
+ )
+ .csrf(c -> c
+ .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
+ )
+ .logout(l -> l
+ .logoutSuccessUrl("/").permitAll()
+ )
+ .oauth2Login();
+ // @formatter:on
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(BlogPostApp.class, args);
+ }
+
+}
diff --git a/BlogPost/src/main/java/com/example/BlogPostService.java b/BlogPost/src/main/java/com/example/BlogPostService.java
new file mode 100644
index 0000000..61f3202
--- /dev/null
+++ b/BlogPost/src/main/java/com/example/BlogPostService.java
@@ -0,0 +1,66 @@
+package com.example;
+
+import java.util.Optional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.client.RestTemplate;
+
+@Service
+public class BlogPostService {
+ @Autowired
+ private RestTemplate restTemplate;
+
+ public String getAllBlogPosts() {
+ ResponseEntity resp = restTemplate.getForEntity("https://jsonplaceholder.typicode.com/posts", String.class);
+ return resp.getStatusCode() == HttpStatus.OK ? resp.getBody() : null;
+ }
+
+ public String getUserBlogPosts(Optional numberOfPosts) {
+ Integer numPosts = numberOfPosts.get();
+ //System.out.println("numPosts="+numPosts);
+ ResponseEntity resp = restTemplate.getForEntity("https://jsonplaceholder.typicode.com/posts/" +numPosts, String.class);
+ return resp.getStatusCode() == HttpStatus.OK ? resp.getBody() : null;
+ }
+
+ public String getAllComments() {
+ ResponseEntity resp = restTemplate.getForEntity("https://jsonplaceholder.typicode.com/posts/1/comments", String.class);
+ return resp.getStatusCode() == HttpStatus.OK ? resp.getBody() : null;
+ }
+
+ public String getPostIdComments(int postId) {
+ ResponseEntity resp = restTemplate.getForEntity("https://jsonplaceholder.typicode.com/comments?postId=" +postId, String.class);
+ return resp.getStatusCode() == HttpStatus.OK ? resp.getBody() : null;
+ }
+
+ public String getUserIdPosts(Integer userId) {
+ ResponseEntity resp = restTemplate.getForEntity("https://jsonplaceholder.typicode.com/posts?userId=" +userId, String.class);
+ return resp.getStatusCode() == HttpStatus.OK ? resp.getBody() : null;
+ }
+
+ public String addPost(ModelMap newBlogPost) {
+ return "If this were a real post, it would have added the form fields to a repository";
+ }
+
+ public String updatePost(ModelMap oldBlogPost) {
+ return "If this were a real post, it would have updated the form fields associated with the postId in the repository";
+ }
+
+ public String patchPost(ModelMap oldBlogPost) {
+ return "If this were a real post, it would have patched the form fields associated with the postId in the repository";
+ }
+
+ public String deletePost(int postId) {
+ return "If this were a real post, it would have deleted the post associated with the postId from the repository";
+ }
+
+ @Bean
+ public RestTemplate restTemplate(RestTemplateBuilder builder){
+ return builder.build();
+ }
+}
diff --git a/BlogPost/src/main/resources/application.yml b/BlogPost/src/main/resources/application.yml
new file mode 100644
index 0000000..af0d3de
--- /dev/null
+++ b/BlogPost/src/main/resources/application.yml
@@ -0,0 +1,12 @@
+spring:
+ security:
+ oauth2:
+ client:
+ registration:
+ github:
+ client-id: 29633ee192bc653fe467
+ client-secret: 4dd48ffb4cf0a468660adb4e8d2fcc6e7efb475d
+
+#logging:
+# level:
+# org.springframework.security: DEBUG
diff --git a/BlogPost/src/main/resources/static/BlogPosts.doc b/BlogPost/src/main/resources/static/BlogPosts.doc
new file mode 100644
index 0000000..3c2d231
Binary files /dev/null and b/BlogPost/src/main/resources/static/BlogPosts.doc differ
diff --git a/README.md b/BlogPost/src/main/resources/static/README.md
similarity index 98%
rename from README.md
rename to BlogPost/src/main/resources/static/README.md
index 03e902d..43a98fd 100644
--- a/README.md
+++ b/BlogPost/src/main/resources/static/README.md
@@ -1,65 +1,63 @@
-# BlogPost
-
-If you would like to see a version of these instructions that contains screenshots, please see BlogPosts.doc instead.
-
-In order to use GitHub as your “single sign-on”, you need to create an account, if you don’t already have one.
-Navigate to the Profile page and enter your Name in the Name field, as shown below:
-
-Open the application code in your favorite IDE. I used Eclipse. I run the application by selecting the top most root,
-right click, select Run As > Spring Boot App. This will build the application and run it. You should see something
-like this in your IDE’s console:
-
-"Started BlogPostApp in 2.327 seconds (JVM running for 3.272)"
-
-Open a browser page and enter "localhost:8080", you should see a web page like this:
-
-Click the “click here” link. You should see:
-
-When you run the Simple app for the first time, you should see something like this:
-
-or this:
-
-Once you click the “Authorize tekknow” button, it will never ask for it again. From now on the application will let you right in
-without having to login, hence the term “single sign-on”.
-
-Once you are authorized on GitHub you should see the full application web page that looks like this:
-
-Notice the “Logged in as TekKnow”. It extracted your name from GitHub.
-When you click the “GET /posts” button, you should see something like this:
-
-And all available posts will be in the table.
-
-When you click the “GET /posts/1” button, you should see something like this:
-
-When you click the “GET /posts/1/comments” button, you should see something like this:
-
-When you click the “GET /comments?postId=1” button, you should see something like this:
-
-When you click the “GET/posts?userId=1” button, you should see something like this:
-
-When you enter data into the “POST /posts” form and click its button, you should see something like this:
-"If this were a real post, it would have added the form fields to a repository"
-Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
-
-When you enter data into the “PUT /posts/1” form and click its button, you should see something like this:
-"If this were a real post, it would have updated the form fields associated with the postId in the repository"
-Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
-
-When you enter data into the “PATCH /posts/1” form and click its button, you should see something like this:
-"If this were a real post, it would have patched the form fields associated with the postId in the repository"
-Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
-
-When you enter data into the “DELETE /posts/1” form and click its button, you should see something like this:
-"If this were a real post, it would have deleted the post associated with the postId from the repository"
-Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
-
-I suspect these errors are related to Cross-Site Request Forgery (CSRF) or permission issues.
-However, they are occuring even before the form data is sent to the server, which is puzzling to me at the moment.
-
-As you study the code, you will notice that there are only two files, BlogPost.java and BlogPostService.java.
-These are both in the "com.example" package. Normally I would have multiple packages like "controller", "model"
-"service", "repository", "exception", etc., where there are many java files in each package. But since this
-was a relatively small project, I just left them in the main com.example package.
-
-
-
+If you would like to see a version of these instructions that contains screenshots, please see BlogPosts.doc instead.
+
+In order to use GitHub as your “single sign-on”, you need to create an account, if you don’t already have one.
+Navigate to the Profile page and enter your Name in the Name field, as shown below:
+
+Open the application code in your favorite IDE. I used Eclipse. I run the application by selecting the top most root,
+right click, select Run As > Spring Boot App. This will build the application and run it. You should see something
+like this in your IDE’s console:
+
+"Started BlogPostApp in 2.327 seconds (JVM running for 3.272)"
+
+Open a browser page and enter "localhost:8080", you should see a web page like this:
+
+Click the “click here” link. You should see:
+
+When you run the Simple app for the first time, you should see something like this:
+
+or this:
+
+Once you click the “Authorize tekknow” button, it will never ask for it again. From now on the application will let you right in
+without having to login, hence the term “single sign-on”.
+
+Once you are authorized on GitHub you should see the full application web page that looks like this:
+
+Notice the “Logged in as TekKnow”. It extracted your name from GitHub.
+When you click the “GET /posts” button, you should see something like this:
+
+And all available posts will be in the table.
+
+When you click the “GET /posts/1” button, you should see something like this:
+
+When you click the “GET /posts/1/comments” button, you should see something like this:
+
+When you click the “GET /comments?postId=1” button, you should see something like this:
+
+When you click the “GET/posts?userId=1” button, you should see something like this:
+
+When you enter data into the “POST /posts” form and click its button, you should see something like this:
+"If this were a real post, it would have added the form fields to a repository"
+Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
+
+When you enter data into the “PUT /posts/1” form and click its button, you should see something like this:
+"If this were a real post, it would have updated the form fields associated with the postId in the repository"
+Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
+
+When you enter data into the “PATCH /posts/1” form and click its button, you should see something like this:
+"If this were a real post, it would have patched the form fields associated with the postId in the repository"
+Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
+
+When you enter data into the “DELETE /posts/1” form and click its button, you should see something like this:
+"If this were a real post, it would have deleted the post associated with the postId from the repository"
+Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
+
+I suspect these errors are related to Cross-Site Request Forgery (CSRF) or permission issues.
+However, they are occuring even before the form data is sent to the server, which is puzzling to me at the moment.
+
+As you study the code, you will notice that there are only two files, BlogPost.java and BlogPostService.java.
+These are both in the "com.example" package. Normally I would have multiple packages like "controller", "model"
+"service", "repository", "exception", etc., where there are many java files in each package. But since this
+was a relatively small project, I just left them in the main com.example package.
+
+
+
diff --git a/BlogPost/src/main/resources/static/index.html b/BlogPost/src/main/resources/static/index.html
new file mode 100644
index 0000000..7352701
--- /dev/null
+++ b/BlogPost/src/main/resources/static/index.html
@@ -0,0 +1,222 @@
+
+
+
+
+
+Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BlogPost/src/main/resources/static/~$ogPosts.doc b/BlogPost/src/main/resources/static/~$ogPosts.doc
new file mode 100644
index 0000000..6fe460f
Binary files /dev/null and b/BlogPost/src/main/resources/static/~$ogPosts.doc differ
diff --git a/BlogPost/src/test/java/com/example/BlogPostTests.java b/BlogPost/src/test/java/com/example/BlogPostTests.java
new file mode 100644
index 0000000..cebf478
--- /dev/null
+++ b/BlogPost/src/test/java/com/example/BlogPostTests.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+public class BlogPostTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/BlogPost/target/classes/META-INF/MANIFEST.MF b/BlogPost/target/classes/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d6001fd
--- /dev/null
+++ b/BlogPost/target/classes/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Implementation-Title: BlogPost
+Implementation-Version: 0.0.1-SNAPSHOT
+Build-Jdk-Spec: 1.8
+Created-By: Maven Integration for Eclipse
+
diff --git a/BlogPost/target/classes/META-INF/maven/com.example/blogpost/pom.properties b/BlogPost/target/classes/META-INF/maven/com.example/blogpost/pom.properties
new file mode 100644
index 0000000..f6ecdb1
--- /dev/null
+++ b/BlogPost/target/classes/META-INF/maven/com.example/blogpost/pom.properties
@@ -0,0 +1,7 @@
+#Generated by Maven Integration for Eclipse
+#Thu Oct 01 20:16:56 MDT 2020
+version=0.0.1-SNAPSHOT
+groupId=com.example
+m2e.projectName=BlogPost
+m2e.projectLocation=C\:\\Users\\Greg\\Projects\\BlogPost
+artifactId=blogpost
diff --git a/BlogPost/target/classes/META-INF/maven/com.example/blogpost/pom.xml b/BlogPost/target/classes/META-INF/maven/com.example/blogpost/pom.xml
new file mode 100644
index 0000000..42de451
--- /dev/null
+++ b/BlogPost/target/classes/META-INF/maven/com.example/blogpost/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+
+ com.example
+ blogpost
+ 0.0.1-SNAPSHOT
+ jar
+
+ BlogPost
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.2.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-client
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.webjars
+ js-cookie
+ 2.1.0
+
+
+ org.webjars
+ jquery
+ 2.1.1
+
+
+ org.webjars
+ bootstrap
+ 3.2.0
+
+
+ org.webjars
+ webjars-locator-core
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/BlogPost/target/classes/META-INF/maven/com.example/social-logout/pom.properties b/BlogPost/target/classes/META-INF/maven/com.example/social-logout/pom.properties
new file mode 100644
index 0000000..2fb8d33
--- /dev/null
+++ b/BlogPost/target/classes/META-INF/maven/com.example/social-logout/pom.properties
@@ -0,0 +1,7 @@
+#Generated by Maven Integration for Eclipse
+#Thu Oct 01 20:06:28 MDT 2020
+version=0.0.1-SNAPSHOT
+groupId=com.example
+m2e.projectName=BlogPost
+m2e.projectLocation=C\:\\Users\\Greg\\Projects\\BlogPost
+artifactId=social-logout
diff --git a/BlogPost/target/classes/META-INF/maven/com.example/social-logout/pom.xml b/BlogPost/target/classes/META-INF/maven/com.example/social-logout/pom.xml
new file mode 100644
index 0000000..f314726
--- /dev/null
+++ b/BlogPost/target/classes/META-INF/maven/com.example/social-logout/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+
+ com.example
+ social-logout
+ 0.0.1-SNAPSHOT
+ jar
+
+ social-logout
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.2.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-client
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.webjars
+ js-cookie
+ 2.1.0
+
+
+ org.webjars
+ jquery
+ 2.1.1
+
+
+ org.webjars
+ bootstrap
+ 3.2.0
+
+
+ org.webjars
+ webjars-locator-core
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/BlogPost/target/classes/application.yml b/BlogPost/target/classes/application.yml
new file mode 100644
index 0000000..af0d3de
--- /dev/null
+++ b/BlogPost/target/classes/application.yml
@@ -0,0 +1,12 @@
+spring:
+ security:
+ oauth2:
+ client:
+ registration:
+ github:
+ client-id: 29633ee192bc653fe467
+ client-secret: 4dd48ffb4cf0a468660adb4e8d2fcc6e7efb475d
+
+#logging:
+# level:
+# org.springframework.security: DEBUG
diff --git a/BlogPost/target/classes/com/example/BlogPost.class b/BlogPost/target/classes/com/example/BlogPost.class
new file mode 100644
index 0000000..46e1770
Binary files /dev/null and b/BlogPost/target/classes/com/example/BlogPost.class differ
diff --git a/BlogPost/target/classes/com/example/BlogPostApp.class b/BlogPost/target/classes/com/example/BlogPostApp.class
new file mode 100644
index 0000000..0c53fb5
Binary files /dev/null and b/BlogPost/target/classes/com/example/BlogPostApp.class differ
diff --git a/BlogPost/target/classes/com/example/BlogPostService.class b/BlogPost/target/classes/com/example/BlogPostService.class
new file mode 100644
index 0000000..7d93fe7
Binary files /dev/null and b/BlogPost/target/classes/com/example/BlogPostService.class differ
diff --git a/BlogPost/target/classes/static/README.md b/BlogPost/target/classes/static/README.md
new file mode 100644
index 0000000..67a6315
--- /dev/null
+++ b/BlogPost/target/classes/static/README.md
@@ -0,0 +1,63 @@
+If you would like to see a version of these instructions that contains screenshots, please see BlogPosts.doc instead.
+
+In order to use GitHub as your “single sign-on”, you need to create an account, if you don’t already have one.
+Navigate to the Profile page and enter your Name in the Name field, as shown below:
+
+Open the application code in your favorite IDE. I used Eclipse. I run the application by selecting the top most root,
+right click, select Run As > Spring Boot App. This will build the application and run it. You should see something
+like this in your IDE’s console:
+
+"Started BlogPost in 2.327 seconds (JVM running for 3.272)"
+
+Open a browser page and enter "localhost:8080", you should see a web page like this:
+
+Click the “click here” link. You should see:
+
+When you run the Simple app for the first time, you should see something like this:
+
+or this:
+
+Once you click the “Authorize tekknow” button, it will never ask for it again. From now on the application will let you right in
+without having to login, hence the term “single sign-on”.
+
+Once you are authorized on GitHub you should see the full application web page that looks like this:
+
+Notice the “Logged in as TekKnow”. It extracted your name from GitHub.
+When you click the “GET /posts” button, you should see something like this:
+
+And all available posts will be in the table.
+
+When you click the “GET /posts/1” button, you should see something like this:
+
+When you click the “GET /posts/1/comments” button, you should see something like this:
+
+When you click the “GET /comments?postId=1” button, you should see something like this:
+
+When you click the “GET/posts?userId=1” button, you should see something like this:
+
+When you enter data into the “POST /posts” form and click its button, you should see something like this:
+"If this were a real post, it would have added the form fields to a repository"
+Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
+
+When you enter data into the “PUT /posts/1” form and click its button, you should see something like this:
+"If this were a real post, it would have updated the form fields associated with the postId in the repository"
+Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
+
+When you enter data into the “PATCH /posts/1” form and click its button, you should see something like this:
+"If this were a real post, it would have patched the form fields associated with the postId in the repository"
+Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
+
+When you enter data into the “DELETE /posts/1” form and click its button, you should see something like this:
+"If this were a real post, it would have deleted the post associated with the postId from the repository"
+Unfortunately, ran out of time. Unable to fix "There was an unexpected error (type=Forbidden, status=403)"
+
+I suspect these errors are related to Cross-Site Request Forgery (CSRF) or permission issues.
+However, they are occuring even before the form data is sent to the server, which is puzzling to me at the moment.
+
+As you study the code, you will notice that there are only two files, BlogPost.java and BlogPostService.java.
+These are both in the "com.example" package. Normally I would have multiple packages like "controller", "model"
+"service", "repository", "exception", etc., where there are many java files in each package. But since this
+was a relatively small project, I just left them in the main com.example package.
+
+
+
diff --git a/BlogPost/target/classes/static/index.html b/BlogPost/target/classes/static/index.html
new file mode 100644
index 0000000..7352701
--- /dev/null
+++ b/BlogPost/target/classes/static/index.html
@@ -0,0 +1,222 @@
+
+
+
+
+
+Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BlogPost/target/test-classes/com/example/BlogPostTests.class b/BlogPost/target/test-classes/com/example/BlogPostTests.class
new file mode 100644
index 0000000..da68a0c
Binary files /dev/null and b/BlogPost/target/test-classes/com/example/BlogPostTests.class differ