stevespringett / alpine Goto Github PK
View Code? Open in Web Editor NEWAn opinionated scaffolding framework that jumpstarts Java projects with an API-first design, secure defaults, and minimal dependencies
License: Apache License 2.0
An opinionated scaffolding framework that jumpstarts Java projects with an API-first design, secure defaults, and minimal dependencies
License: Apache License 2.0
Team API keys should be treated as a secret and not stored in plaintext, instead stored as and compared against the hash. They should not be available on UI like currently in Dependency-Track, except once when generating them. Instead they should get a name and only the name be displayed in UI, to allow identify & delete them.
AlpineTaskScheduler.java
synchronized (this) { EventService.getInstance().publish(event); SingleThreadedEventService.getInstance().publish(event); }
To make parsing in centralized logging solutions like ELK or Splunk easier, applications built on Alpine should be able to emit their logs in JSON format, instead of raw text.
The logback configuration file to use can be overridden at runtime, via -DlogbackConfigurationFile=...
, so users can already adjust the logging behavior to their choosing. However, logback does not have built-in JSON support, so an additional extension is required.
Alpine currently uses maven-surefire-plugin
v2.22.2, the last 2.x release.
This plugin is not compatible with upcoming Maven 4.0.0 and should be upgraded to 3.x. Currently, the most recent plugin release is v3.2.5
Running a build with parameter: -Dmaven.plugin.validation=verbose
provides the following warnings for v2.22.2
* org.apache.maven.plugins:maven-surefire-plugin:2.22.2
Declared at location(s):
* xxx
Used in module(s):
* yyy
Plugin issue(s):
* Plugin is a Maven 2.x plugin, which will be not supported in Maven 4.x
* Plugin depends on plexus-container-default, which is EOL
Mojo issue(s):
* Mojo surefire:test (org.apache.maven.plugin.surefire.SurefirePlugin)
- Parameter 'localRepository' uses deprecated parameter expression '${localRepository}': ArtifactRepository type is deprecated and its use in Mojos should be avoided.
I am logging this as an issue rather than simply providing a PR that updates the version in the POM as I am not a dev and @stevespringett reports that a previous attempt to upgrade the plugin gave problems and was aborted.
Currently, the expiration time for JWT tokens is hardcoded to 7 days in the code. To enhance security measures, it is recommended to allow specifying the expiration time in minutes or hours dynamically.
public String createToken(final Principal principal, final List<Permission> permissions, final IdentityProvider identityProvider) {
final Date today = new Date();
final JwtBuilder jwtBuilder = Jwts.builder();
jwtBuilder.setSubject(principal.getName());
jwtBuilder.setIssuer(ISSUER);
jwtBuilder.setIssuedAt(today);
jwtBuilder.setExpiration(addDays(today, 7)); // Hardcoded expiration time
// ... (additional code)
// Request: Allow dynamic setting of token expiration time (in minutes or hours)
}
Please consider implementing this enhancement for better flexibility and security in managing JWT token expiration times. Feel free to reach out if further clarification.
Feel free to add specific implementation approaches in the comments, and I will try to create a PR by myself as soon as possible.
Best
DoPaNik
Add metrics and related endpoints similar to what DropWizard or SpringBoot provides.
Alpine should contain an AbstractMetricsResource with implementations of the above endpoints. Each application that is built on Alpine would simply extend AbstractMetricsResource so that the app can specify what permissions are necessary for each.
NOTE: It may be possible to simply include Dropwizard Metrics for /health and /metrics capabilities as the module seems to be standalone with minimal dependencies.
Rational: Common to ApiKey and UserPrincipal.
OO simplification to avoid this type of ugly code:
final List<Team> teams;
if (principal instanceof UserPrincipal) {
final UserPrincipal userPrincipal = ((UserPrincipal) principal);
teams = userPrincipal.getTeams();
} else {
final ApiKey apiKey = ((ApiKey) principal);
teams = apiKey.getTeams();
}
Basically now all uncaught errors go to void.
Can be fixed with an addition of a single file ;)
<artifactId>alpine-parent</artifactId>
<packaging>pom</packaging>
<version>2.2.6-SNAPSHOT</version>
You cannot build without downloading this version from Maven or go back to latest available release and hope it will run.
At the moment, when searching for a user in LDAP, the search is executed using only the filter {ATTRIBUTE_NAME}={USERNAME}
.
I don't understand why the USERS_SEARCH_FILTER
is not used in this case.
That should allow to avoid some hicups in badly designed organizations...
What do you think?
I am not arrived to configure LDAP in the application.properties file.
however, I can do a search via ldapsearch
ldapsearch -l 0 -d 0 -vvvv -H ldap://myldap:389/ -b "ou=people,dc=domain,dc=com" -D "uid=myaccess,ou=functionalaccounts,dc=domain,dc=com" -W "uid=myid"
Can you help me ?
persistence.xml currently is used by Alpine applications to define both the classes needing enhancing as well as datastore properties. Properties include items that should be configurable including URL, driver, and username/password.
For executable WARs (including Docker containers), modifying the WAR is not feasible so configuring the database is not easily achieved.
Move datastore configuration to application properties to resolve this limitation.
Currently, JWT authorization is limited to use of the 'Authorization' header where the JWT token is the Bearer. This ticket is to add an enhancement for allowing the JWT to also appear in a cookie named 'Authorization-Token'. If this cooke exists, the value was be used, if the cookie does not exist, the existing logic to check the 'Authorization' header should be used.
Besides the performance improvements and syntactic sugar introduced in Java 17 over Java 11, we should try to stay current by using the latest LTS release. There are some minor roadblocks when building with Java 17 right now. The main blocker right now is DataNucleus not supporting Java 17 in a stable version yet.
I tried to move Alpine and Dependency-Track to Java 17, here's what I've found so far:
6.0.0-m1
(datanucleus/datanucleus-core#359)6.0.0-m4
, build and test run fine. Dependency-Track works as expected as well. Doesn't look like there's much migration work to be done.--illegal-access
flag has been deprecated and doesn't have an effect anymore. This change mostly affects tests as far as I could tell. For example those that try to modify environment variables in some way:
ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.054 s <<< FAILURE! - in alpine.common.util.ThreadUtilTest
[ERROR] determineNumberOfWorkerThreadsTest(alpine.common.util.ThreadUtilTest) Time elapsed: 0.008 s <<< ERROR!
java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: module java.base does not "opens java.util" to unnamed module @7530d0a
configuration
to the surefire plugin:
<argLine>--add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED</argLine>
To remember for what purpose you generated an API key, it would be helpful to store a comment/name/description field.
A mvn clean install
results in the following error message.
[ERROR] Failed to execute goal on project alpine-parent: Could not resolve dependencies for project us.springett:alpine-parent:pom:1.5.1-SNAPSHOT: The following artifacts could not be resolved: com.fasterxml.jackson.core:jackson-annotations:jar:2.9.9.1, com.fasterxml.jackson.jaxrs:jackson-jaxrs-base:jar:2.9.9.1, com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:jar:2.9.9.1: Could not find artifact com.fasterxml.jackson.core:jackson-annotations:jar:2.9.9.1 in central (https://repo.maven.apache.org/maven2) -> [Help 1]
dtrack-apiserver_1 | javax.naming.CommunicationException: <domain>:<port> dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.Connection.<init>(Unknown Source) dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.LdapClient.<init>(Unknown Source) dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.LdapClient.getInstance(Unknown Source) dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.LdapCtx.connect(Unknown Source) dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source) dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxFromUrl(Unknown Source) dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source) dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source) dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source) dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source) dtrack-apiserver_1 | at java.naming/javax.naming.spi.NamingManager.getInitialContext(Unknown Source) dtrack-apiserver_1 | at java.naming/javax.naming.InitialContext.getDefaultInitCtx(Unknown Source) dtrack-apiserver_1 | at java.naming/javax.naming.InitialContext.init(Unknown Source) dtrack-apiserver_1 | at java.naming/javax.naming.InitialContext.<init>(Unknown Source) dtrack-apiserver_1 | at java.naming/javax.naming.directory.InitialDirContext.<init>(Unknown Source) dtrack-apiserver_1 | at alpine.server.auth.LdapConnectionWrapper.createDirContext(LdapConnectionWrapper.java:128) dtrack-apiserver_1 | at alpine.server.tasks.LdapSyncTask.inform(LdapSyncTask.java:59) dtrack-apiserver_1 | at alpine.event.framework.BaseEventService.lambda$publish$0(BaseEventService.java:99) dtrack-apiserver_1 | at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) dtrack-apiserver_1 | at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) dtrack-apiserver_1 | at java.base/java.lang.Thread.run(Unknown Source) dtrack-apiserver_1 | Caused by: java.lang.ClassNotFoundException: alpine.crypto.RelaxedSSLSocketFactory dtrack-apiserver_1 | at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source) dtrack-apiserver_1 | at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source) dtrack-apiserver_1 | at java.base/java.lang.ClassLoader.loadClass(Unknown Source) dtrack-apiserver_1 | at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:511) dtrack-apiserver_1 | at java.base/java.lang.ClassLoader.loadClass(Unknown Source) dtrack-apiserver_1 | at java.base/java.lang.Class.forName0(Native Method) dtrack-apiserver_1 | at java.base/java.lang.Class.forName(Unknown Source) dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.VersionHelper.loadClass(Unknown Source) dtrack-apiserver_1 | at java.naming/com.sun.jndi.ldap.Connection.createSocket(Unknown Source) dtrack-apiserver_1 | ... 21 common frames omitted
Currently when an invalid ApiKey or JWT is provided, only the string Invalid API key asserted
or Invalid JWT asserted
is logged.
Suggested change is to log also IP and User Agent, similar to other security events being logged.
I tried a quick PR to do the as in AlpineResource
but not sure if injecting a HttpServletRequest
here is appropiate. Maybe a global logSecurityEvent
utility method should be made supporting all scenario's.
The following error occurs while dependency-track queries the group filters:
Error occurred during LDAP synchronizationjavax.naming.PartialResultException: Unprocessed Continuation Reference(s)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2917)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2891)
at com.sun.jndi.ldap.AbstractLdapNamingEnumeration.getNextBatch(AbstractLdapNamingEnumeration.java:148)
at com.sun.jndi.ldap.AbstractLdapNamingEnumeration.hasMoreImpl(AbstractLdapNamingEnumeration.java:217)
at com.sun.jndi.ldap.AbstractLdapNamingEnumeration.hasMore(AbstractLdapNamingEnumeration.java:189)
at alpine.auth.LdapConnectionWrapper.getGroups(LdapConnectionWrapper.java:138)
at alpine.tasks.LdapSyncTask.sync(LdapSyncTask.java:97)
at alpine.tasks.LdapSyncTask.inform(LdapSyncTask.java:62)
at alpine.event.framework.BaseEventService.lambda$publish$0(BaseEventService.java:96)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
The LDAP server is Active Directory.
Related configuration properties:
alpine.ldap.enabled=true
alpine.ldap.server.url=ldaps://ad-server.hostname
alpine.ldap.domain=domain.net
alpine.ldap.basedn=DC=domain,DC=private
alpine.ldap.security.auth=simple
[email protected]
alpine.ldap.bind.password=pw
alpine.ldap.auth.username.format=%[email protected]
alpine.ldap.attribute.name=userPrincipalName
alpine.ldap.attribute.mail=mail
alpine.ldap.groups.filter=(&(objectClass=group)(objectCategory=Group))
alpine.ldap.user.groups.filter=(member:1.2.840.113556.1.4.1941:={USER_DN})
alpine.ldap.user.provisioning=true
alpine.ldap.team.synchronization=true
The error occurs, when a user tries to login.
Unfortunately, I cannot share the Active Directory Server configuration.
I think the error should occur for every Active Directory response that has a Referral.
Add a configuration option to let alpine ignore this Exception.
According to https://docs.oracle.com/javase/jndi/tutorial/ldap/referral/jndi.html, the value of Context.REFERRAL
is by default set to IGNORE which means that the LDAP server should not send referrals. However, Active Directory does not support this (see last sentence on the page), and thus the exception is thrown when calling ne.hasMore.
We know the alpine supports the JDK 8 well, how to support the JDK 11? This issue is in JDK 11.
2020-11-30 22:37:11,083 [] INFO [org.eclipse.jetty.util.log] Logging initialized @327ms to org.eclipse.jetty.util.log.Slf4jLog
2020-11-30 22:37:11,244 [] WARN [org.eclipse.jetty.server.Server] ErrorPageMapper not supported for Server level Error Handling
2020-11-30 22:37:11,245 [] INFO [org.eclipse.jetty.server.Server] jetty-9.4.34.v20201102; built: 2020-11-02T14:15:39.302Z; git: e46af88704a893fc12cb0e3bf46e2c7b48a009e7; jvm 1.8.0-262-b10
2020-11-30 22:37:28,691 [] INFO [org.eclipse.jetty.server.session] DefaultSessionIdManager workerName=node0
2020-11-30 22:37:28,691 [] INFO [org.eclipse.jetty.server.session] No SessionScavenger set, using defaults
2020-11-30 22:37:28,693 [] INFO [org.eclipse.jetty.server.session] node0 Scavenging every 660000ms
2020-11-30 22:43:20,787 [] INFO [org.eclipse.jetty.util.log] Logging initialized @317ms to org.eclipse.jetty.util.log.Slf4jLog
2020-11-30 22:43:20,943 [] WARN [org.eclipse.jetty.server.Server] ErrorPageMapper not supported for Server level Error Handling
2020-11-30 22:43:20,945 [] INFO [org.eclipse.jetty.server.Server] jetty-9.4.34.v20201102; built: 2020-11-02T14:15:39.302Z; git: e46af88704a893fc12cb0e3bf46e2c7b48a009e7; jvm 1.8.0-262-b10
2020-11-30 22:43:37,914 [] INFO [org.eclipse.jetty.server.session] DefaultSessionIdManager workerName=node0
2020-11-30 22:43:37,914 [] INFO [org.eclipse.jetty.server.session] No SessionScavenger set, using defaults
2020-11-30 22:43:37,916 [] INFO [org.eclipse.jetty.server.session] node0 Scavenging every 660000ms
2020-11-30 23:24:41,602 [] INFO [org.eclipse.jetty.server.handler.ContextHandler] Started o.e.j.w.WebAppContext@4baf3987{/,file:///C:/Users/mxiao/AppData/Local/Temp/jetty-0_0_0_0-8080-dependency-track-embedded_war--any-3787831117176657565/webapp/,AVAILABLE}{file:/C:/Users/mxiao/code/dependency-track/target/dependency-track-embedded.war}
2020-11-30 23:24:41,626 [] INFO [org.eclipse.jetty.server.AbstractConnector] Started ServerConnector@343f4d3d{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2020-11-30 23:24:41,627 [] INFO [org.eclipse.jetty.server.Server] Started @2481160ms
2020-12-01 00:05:18,635 [] INFO [org.eclipse.jetty.server.AbstractConnector] Stopped ServerConnector@343f4d3d{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2020-12-01 00:05:18,635 [] INFO [org.eclipse.jetty.server.session] node0 Stopped scavenging
2020-12-01 00:05:18,665 [] INFO [org.eclipse.jetty.server.handler.ContextHandler] Stopped o.e.j.w.WebAppContext@4baf3987{/,file:///C:/Users/mxiao/AppData/Local/Temp/jetty-0_0_0_0-8080-dependency-track-embedded_war--any-3787831117176657565/webapp/,STOPPED}{file:/C:/Users/mxiao/code/dependency-track/target/dependency-track-embedded.war}
2020-12-01 00:07:26,922 [] INFO [org.eclipse.jetty.util.log] Logging initialized @425ms to org.eclipse.jetty.util.log.Slf4jLog
2020-12-01 00:07:27,025 [] WARN [org.eclipse.jetty.server.Server] ErrorPageMapper not supported for Server level Error Handling
2020-12-01 00:07:27,026 [] INFO [org.eclipse.jetty.server.Server] jetty-9.4.34.v20201102; built: 2020-11-02T14:15:39.302Z; git: e46af88704a893fc12cb0e3bf46e2c7b48a009e7; jvm 11+28
2020-12-01 00:07:47,168 [] INFO [org.eclipse.jetty.server.session] DefaultSessionIdManager workerName=node0
2020-12-01 00:07:47,169 [] INFO [org.eclipse.jetty.server.session] No SessionScavenger set, using defaults
2020-12-01 00:07:47,170 [] INFO [org.eclipse.jetty.server.session] node0 Scavenging every 600000ms
2020-12-01 00:07:47,189 [] WARN [org.eclipse.jetty.webapp.WebAppContext] Failed startup of context o.e.j.w.WebAppContext@616fe72b{/,file:///C:/Users/mxiao/AppData/Local/Temp/jetty-0_0_0_0-8080-dependency-track-embedded_war-_-any-6145086392483730595/webapp/,UNAVAILABLE}{file:/C:/Users/mxiao/code/dependency-track/target/dependency-track-embedded.war}
java.lang.IllegalArgumentException: object is not an instance of declaring class
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at alpine.Config.expandClasspath(Config.java:510)
at alpine.Config.expandClasspath(Config.java:492)
at org.dependencytrack.upgrade.UpgradeInitializer.contextInitialized(UpgradeInitializer.java:56)
at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:1068)
at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:572)
at org.eclipse.jetty.server.handler.ContextHandler.contextInitialized(ContextHandler.java:997)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:746)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:379)
at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1457)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1422)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:911)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:288)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:524)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:169)
at org.eclipse.jetty.server.Server.start(Server.java:423)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:110)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:97)
at org.eclipse.jetty.server.Server.doStart(Server.java:387)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
at alpine.embedded.EmbeddedJettyServer.main(EmbeddedJettyServer.java:98)
2020-12-01 00:07:47,219 [] INFO [org.eclipse.jetty.server.AbstractConnector] Started ServerConnector@68567e20{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2020-12-01 00:07:47,220 [] INFO [org.eclipse.jetty.server.Server] Started @20726ms
GA-Releases of Java 10 and newer will trigger this error because their version contain only the major version and no minor or patch level.
GA-Release
java -version
java version "15" 2020-09-15
Java(TM) SE Runtime Environment (build 15+36-1562)
Java HotSpot(TM) 64-Bit Server VM (build 15+36-1562, mixed mode, sharing)
first patch level
java -version
java version "11.0.8" 2020-07-14 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.8+10-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.8+10-LTS, mixed mode)
stacktrace from Dependency Track 3.8
2020-10-21 12:15:33,402 [] WARN [org.eclipse.jetty.util.component.AbstractLifeCycle] FAILED ListenerHolder@589da3f3{FAILED}: org.dependencytrack.event.EventSubsystemInitializer: java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError: null
at alpine.Config.<clinit>(Config.java:60)
at alpine.util.ThreadUtil.determineNumberOfWorkerThreads(ThreadUtil.java:43)
at alpine.event.framework.EventService.<clinit>(EventService.java:51)
at org.dependencytrack.event.EventSubsystemInitializer.<clinit>(EventSubsystemInitializer.java:60)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at org.eclipse.jetty.server.handler.ContextHandler$StaticContext.createInstance(ContextHandler.java:2787)
at org.eclipse.jetty.servlet.ServletContextHandler$Context.createInstance(ServletContextHandler.java:1280)
at org.eclipse.jetty.server.handler.ContextHandler$StaticContext.createListener(ContextHandler.java:2798)
at org.eclipse.jetty.servlet.ListenerHolder.doStart(ListenerHolder.java:92)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:72)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:350)
at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1445)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1409)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:825)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:275)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:524)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:72)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:169)
at org.eclipse.jetty.server.Server.start(Server.java:407)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:110)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:97)
at org.eclipse.jetty.server.Server.doStart(Server.java:371)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:72)
at alpine.embedded.EmbeddedJettyServer.main(EmbeddedJettyServer.java:93)
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2
at alpine.util.JavaVersion.<init>(JavaVersion.java:49)
at alpine.util.JavaVersion.<init>(JavaVersion.java:36)
at alpine.util.SystemUtil.<clinit>(SystemUtil.java:48)
It's quite possible that the group management for some applications may happen mostly inside the application itself - not every organisation has the slick automation (xor the slow bureacracy) to manage teams purely in AD / Okta / etc.
For organisations that are happy to manage users within an application, it would be useful to be able to assign a default group to give a good first-login experience, that allows application administrators to grab that user and level their permissions or team memberships appropriately.
Suggest the framework adds a new environment variable:
And any user profile's groups list will be set as a list containing this string.
Update JUnit 4 to 5. OpenRewrite provide a receipe for JUnit Jupiter migration from JUnit 4.x.
See: https://docs.openrewrite.org/reference/recipes/java/testing/junit5/junit4to5migration
As identified in DependencyTrack/dependency-track#218 and DependencyTrack/dependency-track#903, the DataNucleus L2 cache is one of the areas that can prevent Alpine-based applications from being horizontally scalable or HA.
The L2 cache is currently enabled per default. This means that all objects written to the datastore will be cached in-memory:
Objects are placed in the L2 cache when you commit() the transaction of a PersistenceManager. This means that you only have datastore-persisted objects in that cache. Also, if an object is deleted during a transaction then at commit it will be removed from the L2 cache if it is present.
While this behavior works fine for normal CRUD-type applications, it does not for applications like Dependency-Track, that regularly iterate over multiple hundreds of thousands (or millions) of records, and modify them. With record sets in such high numbers, the cost-to-benefit ratio is simply not good.
For applications like Dependency-Track, global usage of the L2 cache is skyrocketing RAM usage, and puts unnecessary pressure on the GC.
Additionally, the L2 cache is only effective when records are fetched by their primary key. In modern applications, lookups by primary key are very rare, as most of them use secondary IDs intended for external consumption (e.g. UUIDs).
In order to support horizontal scalability, high availability, and a generally reduced resource footprint, it should be possible to globally disable the DataNucleus L2 cache.
As a nice-to-have, additional configuration options may be introduced to allow for usage of distributed caches like Redis or Hazelcast (which is supported by DN). Users wishing to utilize these integrations may do so.
Related to DependencyTrack/dependency-track#552
During build, I'm getting a lot of the following exceptions, yet the buiild succeeds.
09:52:43.611 [main] ERROR alpine.server.health.checks.DatabaseHealthCheck -- Checking non-transactional connection pool failed
java.lang.NullPointerException: Cannot invoke "org.datanucleus.store.StoreManager.getBooleanProperty(String)" because "this.storeMgr" is null
at org.datanucleus.store.rdbms.ConnectionFactoryImpl.createManagedConnection(ConnectionFactoryImpl.java:294)
at org.datanucleus.store.connection.ConnectionManagerImpl.allocateManagedConnection(ConnectionManagerImpl.java:408)
at org.datanucleus.store.connection.ConnectionManagerImpl.getConnection(ConnectionManagerImpl.java:213)
at org.datanucleus.store.connection.ConnectionManager.getConnection(ConnectionManager.java:62)
at org.datanucleus.store.rdbms.query.SQLQuery.performExecute(SQLQuery.java:652)
at org.datanucleus.store.query.Query.executeQuery(Query.java:2004)
at org.datanucleus.store.rdbms.query.SQLQuery.executeWithArray(SQLQuery.java:826)
at org.datanucleus.store.query.Query.execute(Query.java:1875)
at org.datanucleus.api.jdo.JDOQuery.executeInternal(JDOQuery.java:439)
at org.datanucleus.api.jdo.JDOQuery.executeResultUnique(JDOQuery.java:393)
at alpine.server.health.checks.DatabaseHealthCheck.executeQuery(DatabaseHealthCheck.java:94)
at alpine.server.health.checks.DatabaseHealthCheck.checkNonTransactionalConnectionPool(DatabaseHealthCheck.java:67)
at alpine.server.health.checks.DatabaseHealthCheck.call(DatabaseHealthCheck.java:48)
at alpine.server.health.checks.DatabaseHealthCheckTest.testWithSecondaryConnectionFactoryDown(DatabaseHealthCheckTest.java:104)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345)
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418)
09:52:43.611 [main] DEBUG alpine.server.health.checks.DatabaseHealthCheck -- Checking transactional connection pool
Wanted to open an issue beforehand in case there's any considerations I'm missing.
I have a use case where team names may be arbitrarily long given they will be based on a path format (ex. folder1/folder2/file).
I propose modifying the Team.java name @Column
to have length of 255 so it matches @Size
max property.
If this sounds reasonable I can open a PR.
The security policy seems to be wrong. How should we report security issues on Alpine?
Cheers,
A
The current stack is based on:
javax.servlet.*
namespace)Community support for Jetty 9.x has ended as of June 1st 2022. There will still be security patches, but it's a good indicator that we should look into updating it. Jetty 11, the latest major release of Jetty, does not support legacy Java EE APIs anymore and is based on the new Jakarta EE APIs instead.
The move to Jakarta requires an upgrade of Jersey to 3.x (migration guide here).
I'm sure there are more dependencies and breaking changes that will pop up once work on this is started.
https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations
The configuration should only apply to the static web content, not any servlets or other dynamic server-generated.
Current Behavior in Dependency Track:
The /team API returns a list of API Keys assigned to a team, but does not provide a timestamp for when each key was created or last accessed. This information is needed to enforce API Key rotation schemas.
...
"apiKeys": [
{
"key": "string"
}
]
Proposed Behavior:
...
"apiKeys": [
{
"key": "string",
"createdAt": "2021-06-09T18:18:21.710Z",
"lastUsed": "2021-06-09T18:18:21.710Z"
}
]
As of this ticket, Java 9 is still in development, but the Flow API (Reactive Extensions) is expected to be included. Abstract this out so that existing apps built on Alpine continue to work, but under the covers it's using Flow API as an implementation rather than it's own.
public void setObjects(Collection<?> object) {
this.objects = objects;
}
public PaginatedResult objects(Collection<?> object) {
this.objects = objects;
return this;
}
Both set the attribute to itself instead of the new parameter.
Each REST resource can be annotated with a permission required. This feature needs to be completed including the data model and filter.
The SecretKey
used for data encryption is currently stored and loaded using Java's object serialization (ObjectInputStream
and ObjectOutputStream
). This is contrasted by the public-private-keypair that is stored in encoded form as byte array.
Alpine/alpine-infra/src/main/java/alpine/security/crypto/KeyManager.java
Lines 230 to 237 in 087f650
Alpine/alpine-infra/src/main/java/alpine/security/crypto/KeyManager.java
Lines 282 to 291 in 087f650
By using Java Object Serialization, it's not possible to supply a key that has been generated outside of Alpine, or more generally outside of Java (e.g. via openssl rand 32
).
For deployment scenarios where multiple applications or instances based on Alpine are working on the same data, it is necessary to generate the keys prior to deployment, and share it across instances.
The secret key saving and loading should be rewritten to handle generic byte arrays, like so:
public void saveEncoded(final SecretKey key) throws IOException {
final File keyFile = getKeyPath(key);
keyFile.mkdirs();
try (OutputStream fos = Files.newOutputStream(keyFile.toPath())) {
fos.write(key.getEncoded());
}
}
SecretKey loadEncodedSecretKey() throws IOException {
final File file = getKeyPath(KeyType.SECRET);
try (InputStream fis = Files.newInputStream(file.toPath())) {
final byte[] encodedKey = fis.readAllBytes();
return this.secretKey = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
}
}
I figure there will need to be some automatic migration logic for existing instances using Alpine, such that the legacy key format would automatically be converted to the new one.
Micrometer allows for customization of its MeterRegistry
via MeterFilter
s.
Filters can be used for various things, but one important capability is to omit, rewrite, or add tags to all metrics.
In order for MeterFilter
s to work, they need to be registered before all Meter
s. Because Alpine does a large chunk of initialization at class loading time, it is currently not possible to add filters in a way that guarantees that they'll be applied to all Meter
s.
ExecutorService
metrics for example are registered in a static { }
block. If the EventService
class is loaded prior to the class adding filters to the registry, the filters will not be applied to ExecutorService
metrics.
Provide a mechanism similar to Spring Boot's MeterRegistryCustomizer
.
The goal of this feature is to allow multiple authentication sources in DependencyTrack/dependency-track
For exemple, allowing login from both Gitlab and Github OIDC providers.
Let me know if you're open to contributions on this subject.
After an initial deployment of dependency-track its is not possible to authenticate as the default admin due to the FORCE_PASSWORD_CHANGE exception never being thrown and LDAP authentication is attempted instead.
}catch(AlpineAuthenticationException e){
// If LDAP is enabled, a second attempt to authenticate the credentials will be made against LDAP so we skip this validation exception.
if (!LDAP_ENABLED) {
throw e;
}
}
As stated in the code comment all ManagedUser exceptions are suppressed and never thrown if LDAP authentication is enabled.
Suggestion is to create different Exception types for different authentication errors.
Hi,
In order to compile on windows, data-nucleus plugin needs fork option to be false. Otherwise it breaks the build by an too many arguments error. Could you please add a profile for windows builds.
org.apache.maven.plugins maven-compiler-plugin ${maven.compiler.plugin.version}To keep track of the purpose of each ApiKey a description field or similar is needed.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.