Skip to content

Commit

Permalink
Migrate to latest Play version - addresses #92
Browse files Browse the repository at this point in the history
- removes last remnants of the deadbolt dependency
- marks users deleted instead of actually deleting them
- re-introduce redirect_uri mechanism
- introduce error report to load-generator
- replaces http error handler with http interceptor
  • Loading branch information
resamsel committed Oct 3, 2020
1 parent 61981c1 commit e6f133f
Show file tree
Hide file tree
Showing 41 changed files with 282 additions and 258 deletions.
4 changes: 4 additions & 0 deletions app/controllers/Auth.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package controllers;

import org.pac4j.core.client.Client;
import org.pac4j.core.exception.http.FoundAction;
import org.pac4j.core.exception.http.RedirectionAction;
import org.pac4j.core.util.Pac4jConstants;
import org.pac4j.play.PlayWebContext;
import org.pac4j.play.http.PlayHttpActionAdapter;
import org.pac4j.play.store.PlaySessionStore;
Expand Down Expand Up @@ -36,6 +38,8 @@ public CompletionStage<Result> login(Http.Request request, String authClientName
@SuppressWarnings("unchecked")
Optional<RedirectionAction> action = client.get().getRedirectionAction(webContext);
if (action.isPresent()) {
request.queryString("redirect_uri").ifPresent(redirectUri ->
webContext.getSessionStore().set(webContext, Pac4jConstants.REQUESTED_URL, new FoundAction(redirectUri)));
return PlayHttpActionAdapter.INSTANCE.adapt(action.get(), webContext);
}
}
Expand Down
30 changes: 1 addition & 29 deletions app/models/User.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package models;

import be.objectify.deadbolt.java.models.Permission;
import be.objectify.deadbolt.java.models.Role;
import be.objectify.deadbolt.java.models.Subject;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.ebean.annotation.CreatedTimestamp;
import io.ebean.annotation.DbJsonB;
Expand All @@ -26,7 +23,6 @@
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand All @@ -44,7 +40,7 @@
@Entity
@Table(name = "user_")
@NameUnique(checker = UserUsernameUniqueChecker.class, field = "username", message = "error.usernameunique")
public class User implements Model<User, UUID>, Subject {
public class User implements Model<User, UUID> {

public static final int USERNAME_LENGTH = 32;

Expand Down Expand Up @@ -195,30 +191,6 @@ public User updateFrom(User in) {
return this;
}

/**
* {@inheritDoc}
*/
@Override
public List<? extends Role> getRoles() {
return Collections.singletonList(UserRole.User);
}

/**
* {@inheritDoc}
*/
@Override
public List<? extends Permission> getPermissions() {
return Collections.emptyList();
}

/**
* {@inheritDoc}
*/
@Override
public String getIdentifier() {
return id != null ? id.toString() : null;
}

public boolean isComplete() {
return username != null && name != null && email != null;
}
Expand Down
7 changes: 2 additions & 5 deletions app/models/UserRole.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
package models;

import be.objectify.deadbolt.java.models.Role;

/**
* @author resamsel
* @version 3 Oct 2016
*/
public enum UserRole implements Role {
public enum UserRole {
Admin("admin"),
User("user");

private String name;
private final String name;

UserRole(String name) {
this.name = name;
}

@Override
public String getName() {
return name;
}
Expand Down
15 changes: 1 addition & 14 deletions app/modules/SecurityModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import auth.CustomAuthorizer;
import auth.CustomCallbackLogic;
import auth.CustomCookieSessionStore;
import be.objectify.deadbolt.java.cache.HandlerCache;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import controllers.routes;
Expand All @@ -29,10 +28,7 @@
import org.pac4j.oidc.config.KeycloakOidcConfiguration;
import org.pac4j.play.CallbackController;
import org.pac4j.play.LogoutController;
import org.pac4j.play.deadbolt2.Pac4jHandlerCache;
import org.pac4j.play.deadbolt2.Pac4jRoleHandler;
import org.pac4j.play.http.PlayHttpActionAdapter;
import org.pac4j.play.store.PlayCookieSessionStore;
import org.pac4j.play.store.PlaySessionStore;
import play.Environment;
import play.inject.Injector;
Expand All @@ -58,9 +54,6 @@ public class SecurityModule extends AbstractModule {
private final Duration cacheTimeout;
private final int cacheSize;

private static class MyPac4jRoleHandler implements Pac4jRoleHandler {
}

public SecurityModule(final Environment environment, final com.typesafe.config.Config configuration) {
this.configuration = configuration;
this.baseUrl = BaseUrl.get(configuration);
Expand All @@ -71,23 +64,17 @@ public SecurityModule(final Environment environment, final com.typesafe.config.C

@Override
protected void configure() {
bind(HandlerCache.class).to(Pac4jHandlerCache.class);

bind(Pac4jRoleHandler.class).to(MyPac4jRoleHandler.class);
// bind(PlaySessionStore.class).to(PlayCacheSessionStore.class);
// com.nimbusds.oauth2.sdk.pkce.CodeVerifier cannot be cast to java.io.Serializable
bind(PlaySessionStore.class).to(CustomCookieSessionStore.class);

// callback
final CallbackController callbackController = new CallbackController();
callbackController.setDefaultUrl(routes.Application.indexUi().url() + "/dashboard");
callbackController.setMultiProfile(true);
bind(CallbackController.class).toInstance(callbackController);

// logout
final LogoutController logoutController = new LogoutController();
logoutController.setDefaultUrl(routes.Application.indexUi().url());
//logoutController.setDestroySession(true);
logoutController.setDestroySession(true);
bind(LogoutController.class).toInstance(logoutController);
}

Expand Down
12 changes: 10 additions & 2 deletions app/repositories/impl/UserRepositoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public String nameToUsername(String name) {
return null;
}

return uniqueUsername(name.replaceAll("[^A-Za-z0-9_-]", "").toLowerCase());
return uniqueUsername(name.toLowerCase().replaceAll("[^a-z0-9_-]", ""));
}

@Override
Expand All @@ -104,7 +104,7 @@ public String emailToUsername(String email) {
return null;
}

return uniqueUsername(email.toLowerCase().replaceAll("[@.-]", ""));
return uniqueUsername(email.toLowerCase().replaceAll("[^a-z0-9_@.-]", ""));
}

/**
Expand Down Expand Up @@ -183,4 +183,12 @@ protected void preSave(User t, boolean update) {
t.username = String.valueOf(ThreadLocalRandom.current().nextLong());
}
}

@Override
public void delete(User t) {
super.persist(t
.withUsername(StringUtils.left(t.username + "$" + t.id, User.USERNAME_LENGTH))
.withEmail(StringUtils.left(t.email + "$" + t.id, User.EMAIL_LENGTH))
.withActive(false));
}
}
2 changes: 0 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ libraryDependencies ++= Seq(
// https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-joda
"com.fasterxml.jackson.datatype" % "jackson-datatype-joda" % "2.10.5",


ehcache,
// "com.typesafe.play.modules" %% "play-modules-redis" % "2.6.0",

Expand All @@ -35,7 +34,6 @@ libraryDependencies ++= Seq(
"org.pac4j" % "pac4j-oauth" % "4.0.3",
"org.pac4j" % "pac4j-oidc" % "4.0.3" exclude("commons-io", "commons-io"),
"org.pac4j" % "pac4j-sql" % "4.0.3",
"be.objectify" %% "deadbolt-java" % "2.8.1",
// https://mvnrepository.com/artifact/org.apache.shiro/shiro-core
"org.apache.shiro" % "shiro-core" % "1.5.3",

Expand Down
1 change: 0 additions & 1 deletion conf/translatr.conf
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ play {
modules {
enabled += "modules.FormattersModule"
disabled += "play.data.format.FormattersModule"
enabled += "be.objectify.deadbolt.java.DeadboltModule"
enabled += "modules.SecurityModule"
# enabled += "play.modules.swagger.SwaggerModule"
enabled += "modules.StreamModule"
Expand Down
2 changes: 1 addition & 1 deletion ui/apps/translatr-admin/src/app/guards/auth.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class AuthGuard implements CanActivate {
url.searchParams.set('redirect_uri', environment.adminUrl + state.url);
this.window.location.href = url.toString();
} else {
this.router.navigate(['/login'], {
this.router.navigate([this.loginUrl], {
queryParamsHandling: 'merge',
queryParams: { redirect_uri: environment.adminUrl + state.url }
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class DashboardPageComponent {
constructor(
private readonly facade: AppFacade,
private readonly router: Router,
@Inject(DASHBOARD_ROUTES) private routes: Array<NameIconRoute>
@Inject(DASHBOARD_ROUTES) private routes: NameIconRoute[]
) {}

routerLink(route: Route) {
Expand Down
7 changes: 1 addition & 6 deletions ui/apps/translatr/src/app/+state/router.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,4 @@ const selectRouter = createFeatureSelector<RouterPartialState, fromRouter.Router
ROUTER_FEATURE_KEY
);

const { selectQueryParams, selectRouteParams } = fromRouter.getSelectors(selectRouter);

export const routerQuery = {
selectQueryParams,
selectRouteParams
};
export const routerQuery = fromRouter.getSelectors(selectRouter);
8 changes: 5 additions & 3 deletions ui/apps/translatr/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FeatureFlagModule } from '@dev/translatr-components';
import { FeatureFlagFacade } from '@dev/translatr-model';
import { NotificationService, TranslatrSdkModule } from '@dev/translatr-sdk';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { HotkeysModule } from '@ngneat/hotkeys';
import { EffectsModule } from '@ngrx/effects';
import { routerReducer, RouterState, StoreRouterConnectingModule } from '@ngrx/router-store';
Expand All @@ -23,9 +24,9 @@ import { AppFacade } from './+state/app.facade';
import { appReducer } from './+state/app.reducer';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { httpInterceptorProviders } from './interceptors';
import { TranslocoRootModule } from './modules/shared/transloco';
import { MatNotificationService } from './services/mat-notification-service';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';

@NgModule({
declarations: [AppComponent],
Expand Down Expand Up @@ -70,12 +71,13 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
{ provide: FeatureFlagFacade, useClass: AppFacade },
{ provide: WINDOW, useFactory: () => window },
{ provide: ENDPOINT_URL, useValue: environment.endpointUrl },
{ provide: LOGIN_URL, useValue: `/ui/login` },
{ provide: LOGIN_URL, useValue: `/login` },
{
provide: NotificationService,
useFactory: (snackBar: MatSnackBar) => new MatNotificationService(snackBar),
deps: [MatSnackBar]
}
},
httpInterceptorProviders
],
bootstrap: [AppComponent]
})
Expand Down
32 changes: 16 additions & 16 deletions ui/apps/translatr/src/app/guards/auth.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,27 @@ export class AuthGuard implements CanActivate {
map(x => x !== null), // null means unauthenticated
tap((authenticated: boolean) => {
if (!authenticated) {
try {
if (this.loginUrl.startsWith('http://') || this.loginUrl.startsWith('https://')) {
if (this.loginUrl.startsWith('http://') || this.loginUrl.startsWith('https://')) {
try {
const url = new URL(this.loginUrl);
url.searchParams.set('redirect_uri', state.url);
this.window.location.href = url.toString();
} else {
this.router.navigate(['/login'], {
queryParamsHandling: 'merge',
queryParams: { redirect_uri: state.url }
});
} catch (e) {
console.error(
'Error while parsing login URL',
this.loginUrl,
this.window.location.href,
e
);
return false;
}
return false;
} catch (e) {
console.error(
'Error while parsing login URL',
this.loginUrl,
this.window.location.href,
e
);
return false;
} else {
this.router.navigate([this.loginUrl], {
queryParamsHandling: 'merge',
queryParams: { redirect_uri: state.url }
});
}
return false;
}
})
);
Expand Down
16 changes: 16 additions & 0 deletions ui/apps/translatr/src/app/interceptors/auth.interceptor.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';

import { AuthInterceptor } from './auth.interceptor';

describe('ErrorInterceptor', () => {
beforeEach(() =>
TestBed.configureTestingModule({
providers: [AuthInterceptor]
})
);

it('should be created', () => {
const interceptor: AuthInterceptor = TestBed.inject(AuthInterceptor);
expect(interceptor).toBeTruthy();
});
});
Loading

0 comments on commit e6f133f

Please sign in to comment.